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分布式锁的探索


Monday, July 29, 2019

Introduction to AWS Storage Gateway

Storage Gateway

Amazon S3
Amazon S3 Glacier (Deep Archive)
Amazon EBS (elastic block store) snapshots

types
- File (protocol NFS, SMB)
- Volume (protocol iSCSI)
- Storage

Friday, February 8, 2019

哭完了继续

最近什么都不给力,无论怎么挣扎都没有好结果。
到后来,最后总是一个人寂寞的哭泣。

不过至少还有自己吧。
就算是不能相信别人,至少还有自己可以相信。
只要自己不要放弃,只要还活着,总能有办法的。

Tuesday, January 15, 2019

最近不想学习。。。

不想学习不想学习不想学习不想学习不想学习不想学习怎么办?

前段时间脑子里有各种 project idea,灵感不断,好奇心旺盛。
现在空空如也,跟死猪一样混日子。。。

什么时候才能重拾兴趣呢?

Most Recent Posts