消息队列高手课
李玥
京东零售技术架构部资深架构师
立即订阅
8426 人已学习
课程目录
已完结 41 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 优秀的程序员,你的技术栈中不能只有“增删改查”
免费
预习 | 怎样更好地学习这门课?
基础篇 (8讲)
01 | 为什么需要消息队列?
02 | 该如何选择消息队列?
03 | 消息模型:主题和队列有什么区别?
04 | 如何利用事务消息实现分布式事务?
05 | 如何确保消息不会丢失?
06 | 如何处理消费过程中的重复消息?
07 | 消息积压了该如何处理?
08 | 答疑解惑(一) : 网关如何接收服务端的秒杀结果?
进阶篇 (21讲)
09 | 学习开源代码该如何入手?
10 | 如何使用异步设计提升系统性能?
11 | 如何实现高性能的异步网络传输?
12 | 序列化与反序列化:如何通过网络传输结构化的数据?
13 | 传输协议:应用程序之间对话的语言
14 | 内存管理:如何避免内存溢出和频繁的垃圾回收?
加餐 | JMQ的Broker是如何异步处理消息的?
15 | Kafka如何实现高性能IO?
16 | 缓存策略:如何使用缓存来减少磁盘IO?
17 | 如何正确使用锁保护共享数据,协调异步线程?
18 | 如何用硬件同步原语(CAS)替代锁?
19 | 数据压缩:时间换空间的游戏
20 | RocketMQ Producer源码分析:消息生产的实现过程
21 | Kafka Consumer源码分析:消息消费的实现过程
22 | Kafka和RocketMQ的消息复制实现的差异点在哪?
23 | RocketMQ客户端如何在集群中找到正确的节点?
24 | Kafka的协调服务ZooKeeper:实现分布式系统的“瑞士军刀”
25 | RocketMQ与Kafka中如何实现事务?
26 | MQTT协议:如何支持海量的在线IoT设备?
27 | Pulsar的存储计算分离设计:全新的消息队列设计思路
28 | 答疑解惑(二):我的100元哪儿去了?
案例篇 (7讲)
29 | 流计算与消息(一):通过Flink理解流计算的原理
30 | 流计算与消息(二):在流计算中使用Kafka链接计算任务
31 | 动手实现一个简单的RPC框架(一):原理和程序的结构
32 | 动手实现一个简单的RPC框架(二):通信与序列化
33 | 动手实现一个简单的RPC框架(三):客户端
34 | 动手实现一个简单的RPC框架(四):服务端
35 | 答疑解惑(三):主流消息队列都是如何存储消息的?
测试篇 (2讲)
期中测试丨10个消息队列热点问题自测
免费
期末测试 | 消息队列100分试卷等你来挑战!
结束语 (1讲)
结束语 | 程序员如何构建知识体系?
消息队列高手课
登录|注册

34 | 动手实现一个简单的RPC框架(四):服务端

李玥 2019-10-12
你好,我是李玥。
上节课我们一起学习了如何来构建这个 RPC 框架中最关键的部分,也就是:在客户端,如何根据用户注册的服务接口来动态生成桩的方法。在这里,除了和语言特性相关的一些动态编译小技巧之外,你更应该掌握的是其中动态代理这种设计思想,它的使用场景以及实现方法。
这节课我们一起来实现这个框架的最后一部分:服务端。对于我们这个 RPC 框架来说,服务端可以分为两个部分:注册中心和 RPC 服务。其中,注册中心的作用是帮助客户端来寻址,找到对应 RPC 服务的物理地址,RPC 服务用于接收客户端桩的请求,调用业务服务的方法,并返回结果。

注册中心是如何实现的?

我们先来看看注册中心是如何实现的。一般来说,一个完整的注册中心也是分为客户端和服务端两部分的,客户端给调用方提供 API,并实现与服务端的通信;服务端提供真正的业务功能,记录每个 RPC 服务发来的注册信息,并保存到它的元数据中。当有客户端来查询服务地址的时候,它会从元数据中获取服务地址,返回给客户端。
由于注册中心并不是这个 RPC 框架的重点内容,所以在这里,我们只实现了一个单机版的注册中心,它只有客户端没有服务端,所有的客户端依靠读写同一个元数据文件来实现元数据共享。所以,我们这个注册中心只能支持单机运行,并不支持跨服务器调用。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《消息队列高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(10)

  • 任鹏斌
    代码拿下来刚消化了一部分,慢慢消化,希望能做一些扩展,一转眼课程要结束了,老师辛苦!
    2019-10-13
    1
  • 陈华应
    抓耳挠腮了两天,还没开始动手,不知道怎么下手~

    作者回复: 先把课后思考题完成了

    2019-10-12
    1
  • 益军
    您好哈,提个疑问:
    服务端业务方法不应该在channelRead0中执行,会导致netty ioEvent线程阻塞,应该异步提交到业务线程池执行
    workers.execute(() -> {
        Command response = handler.handle(request);
        if (null != response) {
            channelHandlerContext.writeAndFlush(response).addListener((ChannelFutureListener) channelFuture -> {
                if (!channelFuture.isSuccess()) {
                    logger.warn("Write response failed!", channelFuture.cause());
                    channelHandlerContext.channel().close();
                }
            });
        } else {
            logger.warn("Response is null!");
        }
    });
     Command response = handler.handle(request);
    2019-12-10
  • 亚洲舞王.尼古拉斯赵四
    看过了这四节rpc的课程之后,再去看了看中KafkaClient及实现的源码,和本篇讲述思想都是相似的,玥哥厉害!还是思想重要,同时觉得期末测试中的状态转换图也是中间件的基本中的基本,重要中的重要的点,KafkaClient这个接口中很多方法都是基于状态字段来给予的返回。(为什么提起状态转换图我就想到了线程的状态转换~~☺️
    2019-11-11
  • 张小勋
    老师 你好~ 本人是net的 最近刚下了 git 的代码 去看了下~有些写法java和net 还是有区别的 问几个问题 希望老师能够作答一下
    首先:helloServiceapi 项目中 建了一个接口 这个接口在服务端去实现 客户端也用到了~ 问下这个接口 在正常的使用中 都是服务端定义好 去给客户端 去使用的么
    第二点:就是在服务端 服务端启动的时候 这个demo 中 是自己去实例化了HelloServiceImpl对象 如果在生产环境中 是不是启动的时候 通过反射 去实例化 那些特定的对外提供的服务 HelloService这样的接口 是不是也要做下标识 是这个思路么
    最后 给自己立下个flag 这个月 自己会去 用netcore+netty+zookeeper 去实现一个RPC 多谢老师

    作者回复: 准确的说,应该是实现定义好接口,服务端和客户端都需要使用这个接口;

    2019-11-08
  • z.l
    请教下老师,如果要实现一个可供生产环境大规模集群使用的注册中心,JDBC协议是不是就不太合适了?这种情况下一个注册中心要满足哪些要求呢?个人盲猜:可多台部署、基于tcp协议最好也是netty实现、彼此之间要保证数据一致性(好像也不用强一致),不知道理解对不对

    作者回复: 大致的要求就是:

    可用性:不能因为某个节点故障导致注册中心不可以;
    数据一致性:能保证顺序一致性一般就可以满足需求了。
    性能:server节点状态变更后,能尽快更新。

    另外,大规模集群情况下,需要考虑业务系统上下线时,注册中心的性能问题。比如:一个几千个节点的微服务上线,会重启几千个Server节点,这时候注册中心需要更新大量的数据。

    2019-11-01
  • zero
    如果服务端挂掉了,怎么通知NameService呢?

    作者回复: 这个问题在我们的demo中并没有解决。实际在生产环境中,有些注册中心会定期检查服务端的状态,但是即使这样也不能保证注册中心中维护的状态和服务端实际的状态实时同步。

    解决这个问题,更多的是依靠rpc框架客户端的自动重试策略,比如,请求某个服务端实例超时后,立即换一个实例自动重试。

    2019-10-30
  • Gred
    来交作业啦【https://github.com/Gred01/simple-rpc-framework/tree/nameservice】,其实本应该在周五就写好了,现在写的demo支持mysql和oracle,初始化sql在rpc-netty底下init-sql.md。

    作者回复: 交作业的都是好同学,👍!

    一个建议:使用PreparedStatement,不要用字符出拼SQL,会有SQL注入漏洞。

    2019-10-28
    1
  • kim118000
    Method method = serviceProvider.getClass().getMethod(rpcRequest.getMethodName(), String.class);
    每次请求都用反射获取method,有没有性能损耗,是不是存起来,请问老师这部分生产级别怎么处理的?

    作者回复: JVM对反射的优化已经很好了,这部分的性能损耗并不是很大,所以一般不用特别的优化。

    2019-10-15
  • leslie
    动手要欠账了:大致明白了RPC整个过程需要什么了,啃几遍梳理一下-看看各个是怎么实现的啃明白再去思考Go怎么实现。。。
    2019-10-12
收起评论
10
返回
顶部