Monday, July 20, 2020

TCP IP 原理

数据库连接 Transaction 保证可以复用


HTTP协议不能共用,相当于IO

无状态,没办法区分不同的requests的replies

如果共用一个连接,没有办法保证reply给到request,必须要对连接上锁,保证一对一


连接 --> 能不能复用 --> 连接数 --> 需不需要close再open

连接pool


ThreadLocal


OSI 7层模型


应用层,表示层,会话层,传输控制层,网络层,链路层,物理层


应用层(,表示层,会话层):应用程序员负责

传输控制层(TCP, UDP),网络层,链路层:内核负责


nc // 创建连接

E.g. 

nc localhost 6379 //connection with local redis

nc www.google.com // then you can send GET HTTP 2.0..


netstat -natp // 看连接


nc是内核负责,HTTP或者redis是应用层


什么是TCP?

面向连接的,可靠的传输协议

三次握手


链接是双向的


三次握手都在传输控制层,内核控制,所以是可靠的

连接走通后,双方需要开辟资源

资源链接后,发送数据


什么是socket?

ip:port + port:ip 四元组,唯一确认/区分每一个 socket 对应关系

ip:主机地址,port:映射进程


port 总共有65535个

对于一个http server端,无论多少socket连接,对于server只消耗一个端口号80

对于一个port用完的client,如果server不一样,还能继续开辟socket (client可以用同样的port)


如果加网卡,还能突破 65535 ports


nc -l 192.168.150.11 9090

netstat -natp //可以看到四元组socket 跟进程之间的映射关系


四次分手

为了释放资源,释放port


When connection sets up, there is:

Client ------SYN-----> Server

Client <---ACK/SYN---- Server ----①

Client ------ACK-----> Server


It takes four segments to terminate a connection since a FIN and an ACK are required in each direction.

and when termination comes, there is:

Client ------FIN-----> Server

Client <-----ACK------ Server ----②

Client <-----FIN------ Server ----③

Client ------ACK-----> Server


tcpdump //抓包程序,自行下载

tcpdump -nn -i eth0 port 80

前三个:三次握手

然后request head, server ack; 

server 分了两次发包 length = 1460, 1321

最后四个是分手


DDoS攻击,就是不发最后的那个ack,占用server资源


网络层


网关 Gateway,掩码 Netmask


UIP & 掩码 = 网络地址

子网掩码(subnet mask)是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。 子网掩码不能单独存在,它必须结合IP地址一起使用。 子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分


网关(Gateway)又称网间连接器、协议转换器。 网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。 网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。“下一跳”


路由表

route -n


找出下一跳

这样就不用把所有的route都存在每一台地址里


链路层


mac 地址,硬件系统

全球唯一


节点,端点


MAC地址换,但是IP地址不换


arp -a


高并发

负载均衡:七层 or 四层


Nginx:七层,基于reverse proxy的load balance

LVS:四层,注意!不能破环连接的原子性




Friday, July 17, 2020

How to resolve circular dependencies in Spring?

Spring 循环依赖

  1. 如何解决

  2. 为什么要使用三级缓存

  3. 如果只保留二级缓存行不行


BeanFacotryPostProcessor

BeanPostProcessor


BeanDefinition -> BeanFacotryPostProcessor 

-> BeanFactory 

-> Init Bean -> BeanPostProcessor (before) -> Init Method -> BeanPostProcessor -- after -> context.getBean() 


区别 FactoryBean:产生特殊对象



Spring 在整个创建过程中,如果想在不同阶段做不同的事情怎么处理?

观察者模式


AbstractApplicationContext  refresh()


refreshBeanFactory

Int multicaster

finishBeanFactoryInitialization(beanFactory)



实例化:开辟内存

初始化:初始值



DefaultListableBeanFactory

getBean(beanName)



DefaultSingltonBeanRegistry 包含三级缓存


singletonObjects; //一级缓存

singletonFactories; //三级缓存

earlySingletonObjects; //二级缓存


每次获取bean对象的时候先从以及缓存中获取值


doCreateBean

createBeanInstance 通过reflection实例化


// Eagerly cache singletons:

addSingletonFactory(beanName, () -> getEarlyBeanReference(..)); // 创建中(实例化,但未初始化)


populateProperty //填充属性

addPropertyValues


resolveValueIfNecessary



在刚刚开始我们创建对象的时候有一个循环

在正常情况下,先创造A,再创建B

但是有循环依赖的时候,在创建A的时候就把B创建了


执行 Anonymous inner class,找到创建中的A

给B中的a赋值

 

创建B对象目的:是再给A对象填充属性的时候发现需要B对象,所以顺带创建了B对象


一级:完整对象,(实例化+初始化都完成)

二级:创建中的对象,实例化完成,但未初始化

三级:实例化完成,但未初始化,获取 Anonymous inner class


3级用来保存获取bean的方法,方法内可以递归调用bean的创建

BeanPostProcessor


AbstractAutoProxyCreator

createProxy


如果在A上配置AOP,是否需要生成一个proxy对象?


exposedObject = ...getEarlyBeanReference(...)









我们需要三级缓存:妮所需要的类有可能是简单对象(实例化,初始化),也可能是需要进行代理的代理对象,当我向三级缓存中放置 Anonymous inner class 的时候,可以在获取的时候决定到底是简单对象,还是代理对象


二级放的是object,三级放的是 object factory



不管在什么时候需要对象,都是在需要的时候通过 Anonymous inner class 来生成,而不是提前放治好了一个对象


Monday, July 13, 2020

Micro service + How to handle HF

微服务架构:


Eureka 注册与发现

Actuator 监控

TrestTemplate 服务器远程调用

Ribbon 负载均衡

OpenFeigh 声明式服务调用

Hystrix 熔断,降级,资源隔离

HystrixDashboard

Zuul 网关

Config 配置中心

Sleuth zipkin 链路追踪



流量介入层


域名服务

动态DNS:把一个域名分布到多个IP,多个机房,去本地的load balancer

分流,延迟降低,容灾

HttpDns:

传统DNS是UDP协议(不可靠,数据更新不及时,tree structure 域名机构太庞大,不安全被劫持),而HttpDns是HTTP,不适合浏览器,适合 mobile app,HTTP 协议接口,参数 = 域名


硬防:防止DDoS之类的,买硬件就好


LVS:part of Linux

LVS:Linux 虚拟机、流量调度,负载均衡

单向的 End user -----> LVS -----> tomcat -----> end user,适合IO密集型

nginx:高性能代理服务器,系统内部流量分发,反向代理

有来回 End user -----> nginx-----> tomcat -----> nginx-----> end user


计算密集型服务:加机器

IO型:扩带宽(比如视屏文件)


有多个LVS

Keepalived:IP漂移


流量网关层

Nginx, Tomcat, Apache Httpd, IIS

LVS不认识后面是谁,需要路由层(网关层组件),硬防是保安,lvs是接待,Nginx是大堂经理

  1. 路由

  2. 流量清洗,防止 SQL injection, XSS, CSRF(网络爬虫),软防

流量网关是双向的,网络IO

需要集群



服务网关,需要集群

Zuul, Spring Gateway

  1. 服务路由

  2. 权限校验


权限

Shiro -> CA server

Spring Security

OAuth2 -> OpenID 我提供的服务,通过你的授权,给第三方的服务用


JWT:会话无状态

初次登录:用户初次登录,输入用户名密码

密码验证:服务器从数据库取出用户名和密码进行验证

生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT

返还JWT:服务器的HTTP RESPONSE中将JWT返还

带JWT的请求:以后客户端发起请求,HTTP REQUEST HEADER中的Authorization字段都要有值,为JWT


JWT token 自带权限信息

权限信息:role + rule (更细腻)


服务网关+服务controller 用 Eureka 来服务注册


微服务

服务controller


Wednesday, July 8, 2020

Dig a little bit deeper into Redis...

特征:

In-memory type

Key-Value pair (Value 可以定义本地方法)

The worker thread is single-threaded; there might be more IO threads

Persistent

同步

集群 → 中间件(本地的,分布式)

 

 

  1. 查询状态

多路复用器

Linux 里面用的是 epoll

  1. Receive and read

  2. 计算

 

 

比较同类型(技术选型)

Memcached: value can only be string.

However, you can serialize more complicated structure 

  1. 全量IO

  2. Need to deserialize,浪费 client 计算力

数据向计算移动

 

Redis: value可以是hashset, list, etc

V: function

E.g. Index(n)

计算向数据移动,(弊端:移动数据成本大于移动计算)

 

 

单线性:需要串行

Read client1 -> calc client 1 -> write client 1 -> read client 2 -> calc client 2 -> write client 2

单线程,串行不一定慢!

 

E.g. 秒杀情景:高并发 vs 并行度

Loads of requests -> Load balancer -> Multi Servers -------> 数据库?

看上去servers是并行的,但实际上因为数据库lock,几乎是串行的

 

Loads of requests -> Load balancer -> Multi Servers ---func: decr----> Redis

Redis内部是串行

 

单线程弊端:只能用一个cpu,不能发挥硬件

如何解决?

增加io threads (read and write),worker thread还是 single-threaded

Netty

 

问题:IO顺序?

IO 执行在kernel上是无序的

但是!在一个request里面是有序的:

无状态协议 e.g. http

通信的层次:3

业务应用层次:可以加 uniqle identifier 来识别消息,以此保证顺序

 

Load balancing: 亲密度/粘性

 

Redis的5大Value类型解析

注意使用场景

 

String

  • String, append, strilen -> json,图片,文件 -> 内存级的文件系统(静态小文件),分布一致性/服务无状态

  • 数值 incr, decr

  • Bitmap

 

二进制安全:redis自己不会做编码/解码,需要提供字节数组, 同理 zookeeper, hbase, kafka

需要统一编码 (utf-8)

 

Bitmap 设计拓展:

setbit [key] [offset] [value]

 

用户统计:

任意时间窗口,给出登录天数?

 

存储时是明细全量时点数据,要是用数据库,超级难 aggregation

但是使用redis bitmap,每个bit可以1 or 0,如果告知offset and length,就可以直接得出登录天数

 

活跃用户数

用日期作为key

使用or在bit上的操作,可以得出在时间窗口里面每天都登陆的活跃用户

 

List

 

底层:Double linked list

可以从left push/ pop, 可以right push/pop

可以模拟 queue 和 stack

 

[lindex]: 数组

 

微服务需要stateless

自身不带private fields,只有methods

Private fields 可以放在redis里面被share

 

Hash

 

E.g.

 

set zsquared::name zz

set zsquared::age 18

 

hset zsquared name zz

hset zsquared age 18

hgetall zsquared → name, zz, age, 18

hkeys zsquared → name, agh

hvals zsquared → zz, 18

 

Set

 

去重,无序,用于交集并集差集

在集群里不推荐使用,或者单独设置set redis:如果在redis集群里面被分散,集合操作会伴随大量IO,干扰性能

应用场景:朋友圈交集,共同好友,推荐好友

 

srandmember: 随机取出无序,参数>0的时候会保证去重,<0时不保证

sunion, sinter, sdiff (left join, right join, inner join)

 

Sorted Set/ ZSet

 

zadd k1 2.2 apple 3.3. orange 1.1 banana → 这里的score是float,有精度差

zrange k1 0 -1 withscores → 从小到大

zrevrange k1 0 -1 withscores → 从大到小

Redis这些方程,能让计算向数据流动

 

如何保持顺序: skiplist

最底下就是普通的linked list

造层是随机的,每层间隔也随机,上面的层也是linked list,相当于2分法方便快速insert(insert 时已经排序了)

 

 

Linux系统的支持:fork、copy on write

 

Redis的持久化:RDB、AOF、RDB&AOF混合使用

 

Persistance: 

  1. Snapshot rdb 恢复快,缺失多

  2. 日志 aof 完整 (慢,冗余)
    1)每次操作,完整IO,但是性能下降一半!

2)每秒,buffer and flush to disk,丢失小于一个buffer

3)靠kernel buffer and flush,丢失一个buffer,经验数据是2G

 

混合使用:

E.g. 8点take a snapshot,然后写日志 aof 追加增量;9点再take a snapshot,抹去之前日志(减量)

 

Redis 到底做数据库还是cache?

只是cache需要持久化么?需要,要不然重启期间request会击垮数据库

 

生产系统之中的问题:

Single point of failure: Master-slave mirror cluster,同步

Pressure test: Sharded cluster,不需要同步

 

通过Redis学AKF划分原则、CAP定理

 

Pressure test: Sharded cluster,不需要同步

强一致性,弱一致性

PAXOS 算法(一半)

 

AKF划分(可用于DB, Redis, web service)

X dimension: master-slave cluster 冗余

Y dimension: divided by business purpose 业务划分

Z dimension: sharding → 去哪台fetch data?

 

How to shard?

 

客户端可以给出映射算法,缺点:所有客户端要统一算法

来一个proxy统一算法,但是single point failure

Redis 自带 算法,映射,虚槽位

 

Redis vs zookeeper分布式锁的探索


Most Recent Posts