|
73 | 73 | #### 7.1 RPC与Dubbo
|
74 | 74 |
|
75 | 75 | 1. 升级作业中的自定义RPC程序:
|
76 |
| - 1)尝试使用压测并分析优化RPC性能 |
77 |
| - 2)尝试使用Netty+TCP作为两端传输方式 |
78 |
| - 3)尝试自定义二进制序列化或者使用kyro/fst等 |
79 |
| - 4)尝试压测改进后的RPC并分析优化,有问题欢迎群里讨论 |
80 |
| - 5)尝试将fastjson改成xstream |
81 |
| - 6)尝试使用字节码生成方式代替服务端反射 |
| 76 | +- 尝试使用压测并分析优化RPC性能 |
| 77 | +- 尝试使用Netty+TCP作为两端传输方式 |
| 78 | +- 尝试自定义二进制序列化或者使用kyro/fst等 |
| 79 | +- 尝试压测改进后的RPC并分析优化,有问题欢迎群里讨论 |
| 80 | +- 尝试将fastjson改成xstream |
| 81 | +- 尝试使用字节码生成方式代替服务端反射 |
| 82 | + |
82 | 83 | 2. 尝试扩展Dubbo
|
83 |
| - 1)基于上次作业的自定义序列化,实现Dubbo的序列化扩展; |
84 |
| - 2)基于上次作业的自定义RPC,实现Dubbo的RPC扩展; |
85 |
| - 3)在Dubbo的filter机制上,实现REST权限控制,可参考dubbox; |
86 |
| - 4)实现自定义Dubbo的Cluster/Loadbalance扩展,如果一分钟内调用某个服务/提供者超过10次,则拒绝提供服务直到下一分钟; |
87 |
| - 5)整合Dubbo+Sentinel,实现限流功能; |
88 |
| - 6)整合Dubbo与Skywalking,实现全链路性能监控。 |
| 84 | +- 基于上次作业的自定义序列化,实现Dubbo的序列化扩展; |
| 85 | +- 基于上次作业的自定义RPC,实现Dubbo的RPC扩展; |
| 86 | +- 在Dubbo的filter机制上,实现REST权限控制,可参考dubbox; |
| 87 | +- 实现自定义Dubbo的Cluster/Loadbalance扩展,如果一分钟内调用某个服务/提供者超过10次,则拒绝提供服务直到下一分钟; |
| 88 | +- 整合Dubbo+Sentinel,实现限流功能; |
| 89 | +- 整合Dubbo与Skywalking,实现全链路性能监控。 |
89 | 90 |
|
90 | 91 | #### 7.2 自定义RPC
|
91 | 92 |
|
92 | 93 | 1. rpcfx1.1: 给自定义RPC实现简单的分组(group)和版本(version)。
|
| 94 | + |
93 | 95 | 2. rpcfx2.0: 给自定义RPC实现:
|
94 |
| - 1)基于zookeeper的注册中心,消费者和生产者可以根据注册中心查找可用服务进行调用(直接选择列表里的最后一个)。 |
95 |
| - 2)当有生产者启动或者下线时,通过zookeeper通知并更新各个消费者,使得各个消费者可以调用新生产者或者不调用下线生产者。 |
| 96 | + - 基于zookeeper的注册中心,消费者和生产者可以根据注册中心查找可用服务进行调用(直接选择列表里的最后一个)。 |
| 97 | + - 当有生产者启动或者下线时,通过zookeeper通知并更新各个消费者,使得各个消费者可以调用新生产者或者不调用下线生产者。 |
| 98 | + |
96 | 99 | 3. 在2.0的基础上继续增强rpcfx实现:
|
97 |
| - 1)3.0: 实现基于zookeeper的配置中心,消费者和生产者可以根据配置中心配置参数(分组,版本,线程池大小等)。 |
98 |
| - 2)3.1:实现基于zookeeper的元数据中心,将服务描述元数据保存到元数据中心。 |
99 |
| - 3)3.2:实现基于etcd/nacos/apollo等基座的配置/注册/元数据中心。 |
| 100 | +- 3.0: 实现基于zookeeper的配置中心,消费者和生产者可以根据配置中心配置参数(分组,版本,线程池大小等)。 |
| 101 | +- 3.1:实现基于zookeeper的元数据中心,将服务描述元数据保存到元数据中心。 |
| 102 | +- 3.2:实现基于etcd/nacos/apollo等基座的配置/注册/元数据中心。 |
| 103 | + |
100 | 104 | 4. 在3.2的基础上继续增强rpcfx实现:
|
101 |
| - 1)4.0:实现基于tag的简单路由; |
102 |
| - 2)4.1:实现基于Weight/ConsistentHash的负载均衡; |
103 |
| - 3)4.2:实现基于IP黑名单的简单流控; |
104 |
| - 4)4.3:完善RPC框架里的超时处理,增加重试参数; |
| 105 | +- 4.0:实现基于tag的简单路由; |
| 106 | +- 4.1:实现基于Weight/ConsistentHash的负载均衡; |
| 107 | +- 4.2:实现基于IP黑名单的简单流控; |
| 108 | +- 4.3:完善RPC框架里的超时处理,增加重试参数; |
| 109 | + |
105 | 110 | 5. 在4.3的基础上继续增强rpcfx实现:
|
106 |
| - 1)5.0:实现利用HTTP头跨进程传递Context参数(隐式传参); |
107 |
| - 2)5.1:实现消费端mock一个指定对象的功能(Mock功能); |
108 |
| - 3)5.2:实现消费端可以通过一个泛化接口调用不同服务(泛化调用); |
109 |
| - 4)5.3:实现基于Weight/ConsistentHash的负载均衡; |
110 |
| - 5)5.4:实现基于单位时间调用次数的流控,可以基于令牌桶等算法; |
| 111 | +- 5.0:实现利用HTTP头跨进程传递Context参数(隐式传参); |
| 112 | +- 5.1:实现消费端mock一个指定对象的功能(Mock功能); |
| 113 | +- 5.2:实现消费端可以通过一个泛化接口调用不同服务(泛化调用); |
| 114 | +- 5.3:实现基于Weight/ConsistentHash的负载均衡; |
| 115 | +- 5.4:实现基于单位时间调用次数的流控,可以基于令牌桶等算法; |
| 116 | + |
111 | 117 | 6. 实现最终版本6.0:压测并分析调优5.4版本。
|
112 | 118 |
|
113 | 119 | ### 8. 分布式缓存
|
114 | 120 |
|
115 | 121 | 1. 基于其他各类场景,设计并在示例代码中实现简单demo:
|
116 |
| - 1)实现分数排名或者排行榜; |
117 |
| - 2)实现全局ID生成; |
118 |
| - 3)基于Bitmap实现id去重; |
119 |
| - 4)基于HLL实现点击量计数。 |
120 |
| - 5)以redis作为数据库,模拟使用lua脚本实现前面课程的外汇交易事务。 |
| 122 | +- 实现分数排名或者排行榜; |
| 123 | +- 实现全局ID生成; |
| 124 | +- 基于Bitmap实现id去重; |
| 125 | +- 基于HLL实现点击量计数。 |
| 126 | +- 以redis作为数据库,模拟使用lua脚本实现前面课程的外汇交易事务。 |
| 127 | + |
121 | 128 | 2. 升级改造项目:
|
122 |
| - 1)实现guava cache的spring cache适配; |
123 |
| - 2)替换jackson序列化为fastjson或者fst,kryo; |
124 |
| - 3)对项目进行分析和性能调优。 |
| 129 | +- 实现guava cache的spring cache适配; |
| 130 | +- 替换jackson序列化为fastjson或者fst,kryo; |
| 131 | +- 对项目进行分析和性能调优。 |
| 132 | + |
125 | 133 | 3. 以redis作为基础实现上个模块的自定义rpc的注册中心;
|
126 | 134 | 4. 练习redission的各种功能;
|
127 | 135 | 5. 练习hazelcast的各种功能;
|
|
132 | 140 | #### 9.1 消息队列原理与应用
|
133 | 141 |
|
134 | 142 | 1. 基于数据库的订单表,模拟消息队列处理订单:
|
135 |
| - 1)一个程序往表里写新订单,标记状态为未处理(status=0); |
136 |
| - 2)另一个程序每隔100ms定时从表里读取所有status=0的订单,打印一下订单数据,然后改成完成status=1; |
137 |
| - 3)考虑失败重试策略,考虑多个消费程序如何协作; |
138 |
| - 4)将上述订单处理场景,改成使用ActiveMQ发送消息处理模式; |
139 |
| - 5)使用java代码,创建一个ActiveMQ Broker Server,并测试它; |
| 143 | +- 一个程序往表里写新订单,标记状态为未处理(status=0); |
| 144 | +- 另一个程序每隔100ms定时从表里读取所有status=0的订单,打印一下订单数据,然后改成完成status=1; |
| 145 | +- 考虑失败重试策略,考虑多个消费程序如何协作; |
| 146 | +- 将上述订单处理场景,改成使用ActiveMQ发送消息处理模式; |
| 147 | +- 使用java代码,创建一个ActiveMQ Broker Server,并测试它; |
140 | 148 |
|
141 | 149 | 2. ActiveMQ/RabbitMQ作业
|
142 |
| - 1)搭建ActiveMQ的network集群和master-slave主从结构; |
143 |
| - 2)基于ActiveMQ的MQTT实现简单的聊天功能或者Android消息推送; |
144 |
| - 3)创建一个RabbitMQ,用Java代码实现简单的AMQP协议操作; |
145 |
| - 4)搭建RabbitMQ集群,重新实现前面的订单处理; |
146 |
| - 5)使用Apache Camel打通上述ActiveMQ集群和RabbitMQ集群,实现所有写入到ActiveMQ上的一个队列q24的消息,自动转发到RabbitMQ; |
147 |
| - 6)压测ActiveMQ和RabbitMQ的性能; |
| 150 | +- 搭建ActiveMQ的network集群和master-slave主从结构; |
| 151 | +- 基于ActiveMQ的MQTT实现简单的聊天功能或者Android消息推送; |
| 152 | +- 创建一个RabbitMQ,用Java代码实现简单的AMQP协议操作; |
| 153 | +- 搭建RabbitMQ集群,重新实现前面的订单处理; |
| 154 | +- 使用Apache Camel打通上述ActiveMQ集群和RabbitMQ集群,实现所有写入到ActiveMQ上的一个队列q24的消息,自动转发到RabbitMQ; |
| 155 | +- 压测ActiveMQ和RabbitMQ的性能; |
148 | 156 |
|
149 | 157 | 3. 演练本课提及的各种生产者和消费者特性。
|
| 158 | + |
150 | 159 | 4. Kafka金融领域实战:在证券或者外汇、数字货币类金融核心交易系统里,对于订单的处理,大概可以分为收单、定序、撮合、清算等步骤。其中我们一般可以用mq来实现订单定序,然后将订单发送给撮合模块。
|
151 |
| - 1)收单:请实现一个订单的rest接口,能够接收一个订单Order对象; |
152 |
| - 2)定序:将Order对象写入到kafka集群的order.usd2cny队列,要求数据有序并且不丢失; |
153 |
| - 3)撮合:模拟撮合程序(不需要实现撮合逻辑),从kafka获取order数据,并打印订单信息,要求可重放, 顺序消费, 消息仅处理一次。 |
| 160 | +- 收单:请实现一个订单的rest接口,能够接收一个订单Order对象; |
| 161 | +- 定序:将Order对象写入到kafka集群的order.usd2cny队列,要求数据有序并且不丢失; |
| 162 | +- 撮合:模拟撮合程序(不需要实现撮合逻辑),从kafka获取order数据,并打印订单信息,要求可重放, 顺序消费, 消息仅处理一次。 |
154 | 163 |
|
155 | 164 | #### 9.2 自定义消息中间件
|
156 | 165 |
|
157 | 166 | 1. v1.0-内存队列:基于内存Queue实现生产和消费API(示例代码已经完成)
|
158 |
| - 1)创建内存BlockingQueue,作为底层消息存储 |
159 |
| - 2)定义Topic,支持多个Topic |
160 |
| - 3)定义Producer,支持Send消息 |
161 |
| - 4)定义Consumer,支持Poll消息 |
| 167 | +- 创建内存BlockingQueue,作为底层消息存储 |
| 168 | +- 定义Topic,支持多个Topic |
| 169 | +- 定义Producer,支持Send消息 |
| 170 | +- 定义Consumer,支持Poll消息 |
162 | 171 |
|
163 | 172 | 2. v2.0-自定义队列:去掉内存Queue,设计自定义Queue,实现消息确认和消费offset
|
164 |
| - 1)自定义内存Message数组模拟Queue。 |
165 |
| - 2)使用指针记录当前消息写入位置。 |
166 |
| - 3)对于每个命名消费者,用指针记录消费位置。 |
| 173 | +- 自定义内存Message数组模拟Queue。 |
| 174 | +- 使用指针记录当前消息写入位置。 |
| 175 | +- 对于每个命名消费者,用指针记录消费位置。 |
167 | 176 |
|
168 | 177 | 3. v3.0-基于SpringMVC实现MQServer:拆分broker和client(包括producer和consumer),从单机走向服务器模式。
|
169 |
| - 1)将Queue保存到web server端 |
170 |
| - 2)设计消息读写API接口,确认接口,提交offset接口 |
171 |
| - 3)producer和consumer通过httpclient访问Queue |
172 |
| - 4)实现消息确认,offset提交 |
173 |
| - 5)实现consumer从offset增量拉取 |
| 178 | +- 将Queue保存到web server端 |
| 179 | +- 设计消息读写API接口,确认接口,提交offset接口 |
| 180 | +- producer和consumer通过httpclient访问Queue |
| 181 | +- 实现消息确认,offset提交 |
| 182 | +- 实现consumer从offset增量拉取 |
| 183 | + |
174 | 184 | 4. v4.0-功能全面:增加多种策略(各条之间没有关系,可以任意选择实现),基于TCP实现server->client,从而实现 PUSH模式
|
175 |
| - 1)考虑实现消息过期,消息重试,消息定时投递等策略 |
176 |
| - 2)考虑批量操作,包括读写,可以打包和压缩 |
177 |
| - 3)考虑消息清理策略,包括定时清理,按容量清理、LRU等 |
178 |
| - 4)考虑消息持久化,存入数据库,或WAL日志文件,或BookKeeper |
179 |
| - 5)考虑将spring mvc替换成netty下的tcp传输协议,rsocket/websocket |
180 |
| -5. v5.0-优化完善:对接各种技术(各条之间没有关系,可以任意选择实现) |
181 |
| - 1)考虑封装 JMS 1.1 接口规范 |
182 |
| - 2)考虑实现 STOMP 消息规范 |
183 |
| - 3)考虑实现消息事务机制与事务管理器 |
184 |
| - 4)对接Spring |
185 |
| - 5)对接Camel或Spring Integration |
186 |
| - 6)优化内存和磁盘的使用 |
| 185 | +- 考虑实现消息过期,消息重试,消息定时投递等策略 |
| 186 | +- 考虑批量操作,包括读写,可以打包和压缩 |
| 187 | +- 考虑消息清理策略,包括定时清理,按容量清理、LRU等 |
| 188 | +- 考虑消息持久化,存入数据库,或WAL日志文件,或BookKeeper |
| 189 | +- 考虑将spring mvc替换成netty下的tcp传输协议,rsocket/websocket |
187 | 190 |
|
| 191 | +5. v5.0-优化完善:对接各种技术(各条之间没有关系,可以任意选择实现) |
| 192 | +- 考虑封装 JMS 1.1 接口规范 |
| 193 | +- 考虑实现 STOMP 消息规范 |
| 194 | +- 考虑实现消息事务机制与事务管理器 |
| 195 | +- 对接Spring |
| 196 | +- 对接Camel或Spring Integration |
| 197 | +- 优化内存和磁盘的使用 |
0 commit comments