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