怪力

个人博客


  • Home

  • Archives

中台

Posted on 2019-05-20
1
2
3
4
5
最近在做关于一些中台的项目,总结下
1.定义中台
2.关于中台的设计
3.关于中台的使用
4.中台的后续沉淀

1.定义中台

刚准备做中台的时候,其实不是很明白,所谓的中台的到底是指的是什么?然后团队的小伙伴们,一起去看了一些关于中台的书,其中就有包括阿里的那本。
当然书是书,具体理解的时候还是不一样的。而且随着业务的不同,中台的一些模式也就不同。
1.业务接入:针对业务,以及一些业务调研场景,首先要思考的是中台的一些能力,具体需要提供哪些能力来服务不同的系统,以及如何满足系统的差异化。
2.基本能力:当时我们讨论了很久,讨论过程中涉及了很多具体的业务方式,发现很多的业务方式实现各有不同,最后只是沉淀了通用的过程,比如相对于考试中台来说,创建卷面、卷面实力、作答、通用性的作答分析、以及一些数据开放、还有基本的数据切分维度等等。
3.系统聚合:对于中台来说,最大的作用是聚合,聚合系统中的共性存在,剥离不同的业务方式,同时降低系统接入成本,对于业务来说,有了更好的使用方式之后,
之后使用的业务增多,再去继续考虑共性抽象。
4.中台和saas: 中台和sass其实不冲突,可以理解为两个维度,一个是公用的抽象,一个是提供不同的业务服务。

2.关于中台的设计

首先中台不会直接对外暴露,这是出于系统安全的角度考虑的。但是又要方便快捷的对接各个业务方,所以中台上层需要对接网关,网关做相应的验签、用户等校验。
1.接入管理:因为需要对外接入,所以中台自然而然需要有一个接入管理,以及按接入方维度的数据吞吐的设计。
2.验签:对于验签,其实是一个通用的逻辑,无非就是根据一些头信息、随机串、参数等等生成一些安全串,然后由被调用方去校验正确性。这里可以抽离成公共包,供业务方使用。
3.调用方sdk:中台需要抽离公共的sdk给其他业务使用,sdk里集成了一些公共的接口,以及一些模型校验等,不同的业务方只需要简单引入就能实现对接。
4.便捷的文档:中台需要提供相应的说明,并且长期维护,告知中台对接信息,以及一些注意事项。

3.关于中台的使用

1.业务化: 中台只是抽离了各个系统间,重合度较高,相对稳定的一些功能,但是到具体业务中,还是存在着部分差异化,
在使用的过程中,需要业务根据自身的情况进行调整,到底是直接使用,还是进行二次封装,可以自己考量。
2.使用方式: 对于使用方来说,中台应该是个黑盒子,直接使用就行,不用去管具体细节。所以对于中台本身来说应该要考虑到使用方的一些在使用上的特点。

4.中台的后续沉淀

由于在中台的路上也才刚刚开始,期待后面接入的业务方的数量的增多,以及各种业务的滋养,会使用中台更加多姿多彩

用户账户

Posted on 2019-03-22
1
2
3
在去年的时候做了用户虚拟账户的设计,后来接手订单后,
断断续续订单出了很多事情,相反账户好像很稳,
就算在订单出现问题的情况下,也没有让公司产生损失,总结下账户的一些情况。

基于TCC的账户设计

账户本身是个金融性很强的操作,公平和稳定才是最大的成功,两段式提交可以尽量保证账户的稳定性。并且就算再出现情况下,也不至于让公司损失资产。
因为账户本身是依赖订单的成功性的,在最终一致性的要求下,需要有可变的账户流水状态进行预扣和返还,同时流水还需要记录账户的变动,包括总金额、每个账户的当前余额、消费额度、以及期末余额,不要觉得没必要记录那么多,当排查问题的时候,你会发现很多好处,记录一目了然,就算真的出现问题,重新扣回来也不是问题。

预扣款:当下单时,订单服务会发送相应的扣款金额,扣款账户等进行预扣款。
扣款:当订单成功时,订单服务会发送相应异步消息,收到消息后,对相应的订单服务进行二次确认,在一系列确认完成之后,进行变更状态操作,这个时候才能算一笔流水成功入库,继续通知相关业务服务进行下一步操作。
返还:一般预扣款之后,会有延迟任务进行返回操作,比如1分钟内,如果订单还是未被确认的,就需要再次确认订单服务的订单是否还是有效订单,把相应的钱款返回到账户,当然这里和订单机制有关,有些系统的设计是订单有效期内,下单还是会返回当前订单的,这里就需要相应的服务进行方案确认了。

预扣款的时候排队扣款问题:预扣款应当是同步和幂等的,不会对相同的订单重复扣款,对于用户来讲扣款应该是有序的
扣款:扣款应该是经过准确校验的、幂等的同一个订单不能扣款两次
返还:返还的时候必须要确认订单的相关信息,看看到底是返还是扣款,同样这里也是需要幂等的

当然还有很多的账户功能,就不在这里做叙述了,主要是为了描述一些TCC的设计。

订单和账户的对账

对账可以帮忙发现很多问题,不管是订单的还是账户,如果两边收入支出不平衡,可以发现一些错误的订单或者账户流水。
可以发现问题的方式都是好方式,不管是从财务上还是从技术本身。
对账就需要设计相应的流水记录,每个项目的对账方式可能都有不同的地方,所以在设计账户流水的尽量将对账的相关考虑进去。

报警和日志

相关的报警和日志还是比不可缺的,没有相关健全的保障措施,会让查找问题和排除等有很大的局限性,没有及时发现问题的措施,会让损失持续扩大化,可能最后不得不停服务采取这样的措施来解决。

苹果支付

Posted on 2019-03-19

苹果支付的一些问题

1.苹果支付的传递只能通过app本身传递,存在了很多的不确定性,在应用崩溃等情况时,会丢失订单号
2.传输问题,app客户单的网略情况没有服务器的传输稳定,在网络波动的情况下,会出现接收不到验证信息的情况
3.服务器向苹果验证时的网络问题,这里概率不是很高,但是偶尔也是有的,验证会有超时等等的现象
4.苹果服务器返回问题,偶尔存在服务器返回的时候,丢失了一部校验数据
5.订单返回商品存在多个订单的商品信息,连续多次下单或者曾经订单处理不及时的情况下,苹果会存在合并订单的情况

针对苹果订单的一些处理

1.对于丢失订单号的情况,需要针对用户本身获取相应订单,验证订单商品一致,对商品等校验后,将相应权益给到用户账户
2.保证重试,这里有两个地方,app与服务器之间的重试,服务器与苹果服务器之间的重试。
与app协定重试策略,让app添加定时器,每隔一段时间重试一次,并有一个最终重试机制。超过最终重试之后,每次app打开的时候验证向服务端验证等。
服务器验证方面则需要在网络错误的情况下记录到库,后续去做重试操作,最好标记次数等。
3.苹果存在合并订单的情况,需要去查询用户购买的相关产品,做好产品编号和交易号的校验,进行异步补偿处理。(ps:谁也不知道接手的项目之前卖过什么类型的商品)

事务问题

订单情况下,事务问题有时候排查起来比较困难,特别又涉及了分布式调用情况。
1.事务拆分,尽量不要在订单流程中使用大事务,如果有大事务,尽量拆分到不同的小事务
2.事务引发的脏读问题,因为事务本身具有隔离性,当事务没有提交的时候,会导致读取的情况不一样,
在订单的强一致性下,这样的情况显然不能接受。可以在拆分细的事务后,使用高可用消息中间件,解决最终一致性问题

缓存问题

在和订单相关的服务调用的时候容易产生,特别在和事务的情况融在一起时,就更加复杂。我刚接手代码的时候,很多地方的写法都排除了这样的况,导致问题出现频繁,但是对于缓存的情况,并没有通用的解决方案,只能在相应的情况下做出处理。

异步化问题

1.异步是个通用的解决模型,能通过异步消息解决很多问题。比如账户和订单之间。
这里要说的是异步化不要在事务中进行,我早期接手代码的时候,发现很多消息竟然是嵌入在事务里面的,
这里就为消息本身带来很多不确定性,发送应该在事务完整结束之后。

幂等

保证幂等是基本要求

分布式问题

需要处理好对于分布式相关的调用问题,以及分布式锁使用的情况

订单情况排查

日志入库:相应的关键位置的日志应该入库操作,毕竟是涉及用户金钱的,相关位置还是要记录一下的
报警:接入相应的监控,当出现问题时,可以及时的处理,不造成损失扩大
这里具体的方案应该每个公司都会有一些相应的基础设施,可以对接相应的部门获取,如果是一些创业型公司,可以用db、邮件服务等再相关位置做发送也是可以的。

网络基础

Posted on 2019-02-13

网络分层

1
2
3
4
5
应用层: DHCP、HTTP、HTTPS、RTMP、P2P、DNS、GTP、RPC
传输层: UDP、TCP
网络层: ICMP、IP、OSPF、BGP、IPSEC、GRE
数据链路层: ARP、VLAN、STP
物理层: 网络跳线

协议套件

举例网络正常传输过程

1.一个请求从浏览器请求服务器时,服务器收到了浏览器的请求后
2.内容、http头、tcp头、ip头、mac头被包装后进行发送
3.首先被摘掉的是mac头、ARP会发出广播查看这个包能被哪位仁兄接收
4.当包被下层接收后,会取下ip头查看是否是发给我自己的,如果是就留下,不是就进行转发
5.如果是自己的,则丢给应用,因为tcp里面有端口号
6.这个应用估计就是个浏览器了,取下http头,根据内容展示相应的内容
参考资料 ARP


总结:层与层的关系更是包含关系,每层其实都是完整的包,只是每层对应做的事情不一样而已。可以没有上层,但是不能没有下层。

但是这样还有很多问题,比如
1.ARP只能支持同一个网段的通信
2.IP地址是怎么来的,又是怎么没的
3.等等…

媒体访问控制 MAC

当电脑配置好ip地址,通过集线器连接之后,就能正常广播网络包了,
但是这里不能乱,要制定收发的规则(谁先发,谁后发等。),错误处理等等,这就需要MAC来解决。这里有个名词叫做多路访问。至于发给谁,谁接收,就需要mac地址来解决,这玩意号称全世界唯一不重复。类似于身份证。在发送的时候,带上目标的MAC地址和源MAC地址,以及相应的类型(ARP;IP数据报),就能被收到了。还有一个问题,就是在以太网中,知道了ip地址,确不知道mac地址,那怎么办,这里就需要ARP,广播出去,谁是这个ip的,谁来回答,收到回到后,将包发送过去。然后将目标ip和mac缓存起来。


总结下:
1、mac层主要解决了多路访问控制,接收靠的是网络格式
2、ARP主要是广播形式

DHCP

linux有自己设置ip的命名,比如ifconfig。
但是也不是怎么配置都可以的,如果配置的ip不正确,容易造成网络包发送不出去。
比如身处网络192.168.1.x的网络环境,私自将ip配置了10.100.158.47,如果需要将网络包发送到192.168.1.x上,网络包是出不去的。首先这里不知道目标的mac的地址,跨网段调用需要网关,还需要配置网关的地址,才能将包发到对应的机器上。
所以配置ip是一件比较麻烦的事情,才有了dhcp简称动态主机配置协议。
dhcp的工作方式大概是这样的,当需要加入这个网路的时候,但是确没有ip地址,则会发送bootR(bootRequest)以0.0.0.0的ip地址,发送目标地址255.255.255.255,带着自己的mac地址以广播的形式发送,这时,如果有存在dhcp server就会有相应,将加入的机器的回应以广播的形式再发送回去,还将子网掩码、网关、ip地址租用期等信息返回。如果存在多个dhcp server,一般会取收到的第一个作为回应,同样是个广播,等dhcp server确认后,才确定了信息,可以进行联网访问。

网络拓扑结构

简单来说,是因为局域网与局域网之间互相连接形成的比较复杂化的网络结构。交换机通过广播方式学习到网络拓扑结构。
网络环路的产生:机器ARP发出去的包,分别被多个交换机学,交换机在收到机器自身发送的ARP包和别的交换机发送的ARP包对应的网口位置不同造成了学习混乱,不停地发送ARP。
环路解决: STP协议,会根据BPDU,把其中的线路切断只保留单个交换机的链路,拆条环形后基本也就是树形结构,简称生成树协议
STP协议:
STP介绍
广播问题和安全:
如果网络广播都是全链路发送的话,如果导致一些机密的信息被抓包,会产生一些隐患。
VLAN
需要交换机支持VLAN,而层头协议上会增加一个tag字段,里面新增了vlanID,这样交换机就知道数据包发到哪里了。

联网

mac ip 头

其实在我看来,联网其实是个查找的过程。了解下NAT
NAT,
在整个过程中,数据需要被一次又一次的转发.
例:
设备A的ip地址是192.168.1.101需要连到设备B 192.168.5.11
首先A、B不在一个局域网,A将包发出去,需要经过路由器转发,一般路由器的地址为该网段的第一个或者第二个
1.通过ARP,获取路由器连接在该设备A的端口的MAC地址
2.得知目标mac地址之后,发送数据包
3.路由器需要判断下一跳从哪里发出去,得知之后,ARP获取下一跳的MAC地址,替换目标MAC地址为下一跳
4.NAT改变源MAC地址和源IP地址的公网身份
5.反复步骤3,设备B收到数据包

路由

路由需要学习,选择最短的路径自然能提高网络传输的速度,路由器与路由器之间通过相互传递,构建网络图,寻找最短距离。
基于bellman-ford的距离矢量路由算法
基于dijkstra链路状态路由算法
动态路由协议:
OSPF:开放式最短路径优先
一般用于内部网络,基于链路状态路由算法。
BGP:外网路由协议
用于外部网络,基于距离矢量路由算法。

关于生病

Posted on 2018-12-25

心态

生病的心态一般来讲也不会太好,反正我第一刻倒是有点懵逼的。
1.体检的时候,查出了一些问题,提醒我去医院复查。
2.周末去医院复查,约了一些检查项,检查的时候,负责B超的医生就已经告知有问题,可能需要手术
3.得知后懵逼一下午,然后挂了个普外科的号,去问了下医生,让我甲状腺两边全切
4.第一时刻也不知道是什么病,所以暂时没有答应立即住院的建议

纠结

纠结于到底要不要去手术?心情也不是很好,知道有问题后,总归有点……
1.回家先自己查了相关资料,比如相对应类型的病症啊,有什么治疗方式等等
2.托朋友问了一些主治医生,是不是必须手术等等
3.汇合所有建议,发现只能去做手术,那也好只能躺着被割了
4.还差一步,通知家人相关的信息,并安排下时间照顾(当然自己很牛逼完全不需要别人照顾也OK)
5.预约相关比较权威的医院,找一位可以主刀的主治医师(在该病症方向),询问病情呀,手术相关的一些事宜后,安排住院流程

住院以及手术

住院很无聊
1.手术前要手术前检查,一般提前3天到入院
2.入院后,会组织相关检查
3.手术前一天不能吃东西
4.手术当天,护士也会嘱咐一些东西,遵循便是
5.手术当天等待手术室安排,在病房不要乱走
6.手术被宰割

术后

术后前期还是挺痛苦的
1.麻药副作用反应 总之我是比较痛苦,吐了整整一晚上,虚弱~,整整两天没吃没喝(手术前一天晚上开始)
2.每天固定的常规检查和挂水
3.手术伤口,存在活动不方便
4.每天安静等待。。。。。。。。。

网站演进

Posted on 2018-11-14

初始阶段网站架构

应用程序、数据库、文件系统都在一台服务器上,开搞

应用服务和数据分离

应用程序单节点在单独的服务器上,数据库、文件系统分别在别的服务器上

缓存改善

缓存热点数据,应用程序访问分布式缓存、或者本地缓存来提高性能

应用服务器集群化

当单台应用服务器满足不了性能需求之后,通过扩展应用服务,来进行伸缩,挂载负载均衡服务器来提供高性能的服务

数据库读写分离

应用程序读操作会读取只读数据库,写操作时写入写数据库,读写实现主从复制,从而提高性能

反向代理和CDN技术

为了加快网站的访问,可以使用反向代理和cdn,它们的基本原理都是缓存,区别在于cdn部署在网络提供商的机房,可以让用户从离自己最近的网络机房获取数据。反向代理是部署在自己的中心机房,当发现有数据的时候,直接返回,不访问应用服务器。

分布式数据库和分布式文件系统

分布式数据库是网站数据库拆分的最后手段,只有在单表数据非常大的时候,并且没有什么很好的解决方案的时候才会考虑去做。不到万不得已的时候,网站更常用的拆分手段是按业务分库,不同的业务数据库部署在不同的服务器。

nosql和搜索引擎

当网站的存储和检索需求越来越复杂时,应用程序访问统一的数据访问模块,减轻应用程序管理多数据源的麻烦。

业务拆分

对应用程序进行业务拆分,业务之间通过消息服务、网络等进行数据分发和存储

业务抽象

对不同的业务,分别进行高度抽象,聚合业务,独立部署,通过分布式调度完成整体业务线

演进小结

不论是怎么演进,任何网站都是从小到大,没有一蹴而就的大型网站。业务与技术的相互性,业务到一定的程度会成就技术,技术的进度反之推动业务增长,提高效率等。做出最适合目前的业务的技术架构才是最合适的,随着发展慢慢的增长和扩大,更是一个健康的发展规律。

架构模式

分层

分层是单一职责的体现,尽量让项目可维护和结构化,保证业务逻辑清晰。一般来讲,计算机世界,加一层可以解决很多问题,但是也会带来一些问题,具体要在项目中去权衡利弊,总归人生都是博弈,没有博弈的架构也缺少了很多刺激。

分割

保证业务的保持在一定的颗粒度和可维护性

分布式

分割和分层之后才更利于多部署,保证更高的可用性能,提供更可靠的服务。
综合考量分布式的适用情况,因为分布式也会有别的情况产生,分布式后服务调用必然通过网络,
这可能对性能开销也是有影响的,服务器越来越多,维护和管理也是个问题。
应用本身,在分布式上也存在着很多问题,不要为了分布式而分布式。
分布式:
分布式应用和服务
分布式静态资源
分布式数据和存储
分布式计算

架构要素

1.性能
2.可用性 4个9?哈哈哈
3.伸缩性
4.扩展性
5.安全性

nginx事件机制

Posted on 2018-10-24

ngixn事件

主要是说nginx对TCP网络事件的管理,但是对于系统底层关于这块的管理又不全是一样。
比如linux 2.6之前的版本或unix大部分是poll或者select,2.6以后用的epoll.
分别对应于nginx的处理就是ngx_poll_module、ngx_select_module、ngx_epoll_module,
当然还有其他针对别的操作系统的事件模块。

事件的创建

事件创建是不需要被创建的,nginx会在启动时,预分配所有的读事件和写事件,只需要调用相应的方法,往事件模块中增加或者删除事件。
每一个连接会对应一个读事件,一个写事件。
读事件:当读事件被添加到事件驱动模块中时,对应该事件的TCP连接上一旦出现可读事件就会回调该事件的handler方法。
写事件:当写事件被添加到事件驱动模块中,写事件被操作时,当连接对应的套接字缓冲区中有可用空间时,事件收集器会处理这个可写事件。

ngixn对连接的定义

对于web服务器,每一个用户需要至少对应一个tcp连接,一个连接至少需要一个读事件,一个写事件。同时,还会有向上游服务器(这里请了解反向代理相关概念)请求的连接,
ngx_ connection_ t 连接池由connections和free_connections组成,connections是指向整个连接池数组的首部,free_connection是指向第一个空闲连接,连接之间又会形成一个单链表。
连接与事件:连接池、读事件、写事件、分别是三个一一对应的数组根据数组序号就可以将连接和事件对应起来

核心模块

ngx_events_module会在nginx启动时调用,会由ngx_event_core_module模块决策到底使用哪种机制去管理事件。如下图:

ngx_event_core_module

1.打开accept_mutex配置,
2.关闭ngx_use_accept_mutex锁
3.初始化红黑树实现的定时器
4.调用配置项指定的事件模块的Init方法
5.指定timer_resolution毫秒后调用ngx_timer_sigal_handler方法
6.向cycle->files数组预分配运行时使用的连接句柄
7.预分配cycle->connections数组充当连接池
8.预分配所有读事件到cycle->read_events数组
9.预分配所有写事件到cycle->write_events数组
10.将上述3个数组中相同序号下的读写事件放置到connections连接中
11.讲connections数组的连接构成单链表,由cycle->free_connections指向空闲连接首部
12.设置监听端口上读事件的处理方法
13.讲监听连接的读事件添加到时间驱动模块

epoll事件驱动模块

这个模块来看一下ngx_epoll_module如何基于epoll实现nginx的事件驱动,同时可以看看如何在nginx如何在几十万并发连接下做到高效利用服务器资源的。
场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收到TCP包),也就是说,在每一时刻,进程只需要处理这100万连接中的一 小部分连接。那么,如何才能高效地处理这种场景?
先来看看select和poll事件: 把这100万个连接告诉操作系统,然后由操作系统找出其中有事件发生的几百个连接。如果每次收集事件时,都把这100万连接的套接字传给操作系统,而由于用户态内存到内核态内存的大量复制,并且内核在寻找这些连接上没有处理事件会有很大的资源浪费。
附上linux图谱一张
epoll方式:将原先的select、poll方式分成了3个部分,epoll_create建立epoll对象,调用epoll_ctl向epoll对象添加这100万个连接套接字,调用epoll_wait收集发生的事件的连接,epoll_wait的效率显然非常高。所有添加到epoll中的事件都会与设备驱动程序建立回调关系。相应的事件在发生的时候会调用这里的回调方法。这个回调方法在内核中兼做ep_poll_callback,这些事件会被添加到双向链表中。epoll_wait检查是否有事件发生的连接只是检查双向链表是否存在元素而已。事件的查找是基于红黑树来实现的,也非常快。

事件驱动框架处理流程

1.accept方法建立新的连接
2.设置负载均衡阈值
3.连接池中获取一个连接
4.为连接分配内存
5.设置新的套接字属性
6.添加连接到epoll监控
7.处理新连接

解决负载群惊

群惊:程序开始监听web端口,fork多个子进程,这些子进程开始同时监听同一个端口,一般情况下,子进程数量和cpu核心数相同。如果没有用户连接服务器,某一个时刻恰好所有子进程都休眠且等待新连接的系统调用,这是有用户请求,内核收到SYN包后会激活所有子进程,当然,只有最开始执行accept的进程可以成功建立连接,但是其他的进程已经被唤醒了,这唤醒是不必要的浪费资源。
nginx在这里加了一步进程间的同步锁,只有获取到锁的进程才能监听web端口处理事件。关于锁的释放并不是在所有都处理完后释放,这样估计就单进程模式了。这边nginx是分开新连接的事件队列和普通的事件队列去解决的。区分之后会处理新连接队列,处理后立即释放锁资源。

文件的异步IO

这里的文件IO也是基于Linux底层实现的。Nginx把读取文件的操作异步提交至内核后,内核会通知IO设备独立执行,这样Nginx会继续充分占用cpu,当大量读事件堆积时,电梯算法优势会被发挥,降低随机读取磁盘的成本。
异步的io是不会读取文件缓存的,就算当前要被读取的文件存在io设备的缓存中,也是不会去读取的,所以选择异步IO的还是要看实际应用场景。

nginx与tcp


建立连接是在内核中完成的(上图),nginx只是从内核中获取了该连接。
如果accept中取出不及时,可能会导致linux的accept队列满,会影响导致syn队列满,而导致服务器无法再建立连接。

send方法内核示意图

rev方法内核示意图

动态代理浅说

Posted on 2018-10-18

代理应该学习java的都不陌生了,不过之前我学习的时候倒是有疑问的,这么做到底意义在哪里?
它能帮我干些什么?

剥离非业务逻辑

举个例子,例如事务,每次使用的时候都需要打开,然后提交等操作
这些操作如果在每次的业务线上去做的时候,这是一件繁琐的事情,业务代码的人也并不需要关心,对于他这个角色来说,
处理好业务代码应该就可以了。那这部分就可以使用代理让它去帮你完成这部分操作。
当然spring已经封装好了,没必要再实现一遍

制定通用的一些策略

其实这个很笼统,什么样的策略是通用,从业务上理解就是大部分场景需要这些操作,但是又不想多处维护,方式等也都比较统一的策略

实现比较优雅的模式

JDK Proxy

这里其实有很多文章说明
实现接口 -> 实现invocationHandler -> newProxyInstance -> invoke
newProxyInstance 这里会生成字节码 既然是动态代理总得有动态代理的意义 ^_^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
try {
Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
                                 0, proxyClassFile.length,
                                loader, null);
reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
return pc;
} catch (ClassFormatError e) {
// 如果出现 ClassFormatError,很可能是输入参数有问题,比如,ProxyGenerator 有 bug
}

public static Object newProxyInstance(ClassLoader loader,
                                  Class<?>[] interfaces,
                                  InvocationHandler h)

ASM是通过操作字节码来实现对结构的修改和包装的。
如:Visitor
Jdk proxy

CGLIB

基于AMS的CGLIB,应该也没有人陌生
字节码生成子类 -> 动态生成类和方法等-> 包装父类和子类 -> 索引代理方法和被代理方法 -> 调用
字节码文档
cglib

杂说

Posted on 2018-10-18

关于博客,之前也写过一点,但是始终没有坚持下来。
一是觉得墨水太少,怕辣到各位眼睛
二是写起来也挺烦,自我督促能力不够强
其实还是有必要写的,自我总结和学习嘛
以前写过的一些前端的小菜鸡文章就删了
现在开始写关于java的小菜鸡文章
嗯,先这样,但愿可以坚持下去

怪力

个人博客

9 posts
6 tags
© 2019 怪力
Powered by Hexo
|
Theme — NexT.Muse v5.1.4