【从零搭建后端基础设施系列(十)】-- 服务发现与治理(中)

==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍


没有看过上篇的点这里【从零搭建后端基础设施系列(十)】-- 服务发现与治理(上)

  • CODE

  • 效果演示

    • 启动注册中心,并将三个服务注册到注册中心
      注册服务
      在这里插入图片描述
      在这里插入图片描述

    • 启动服务治理
      启动服务
      在这里插入图片描述

    • 启动最小系统thrift服务
      在这里插入图片描述

    • 启动最小系统web服务
      在这里插入图片描述

    • 再来看看服务治理的日志
      已经有两个服务的机器信息上报到这里了。
      在这里插入图片描述

    • 接下来发送一个http请求看看

      在这里插入图片描述
      接口全部通了。

    • 将web服务重启看看会发生什么
      在这里插入图片描述

    • 将thrift服务重启看看会发生什么
      在这里插入图片描述
      但是你会发现,web调用thrift的时候报错了
      在这里插入图片描述
      很明显,连接失效了。在这里插入图片描述

  • 现象分析

    • 为什么需要按照这样的顺序启动?
      注册中心必须先启动,因为它需要存储其它服务的信息
      服务治理启动需要依赖注册中心,因为后续其它服务上报机器信息的时候,需要判断该服务是否已经注册。
      然后到thrift服务,因为它需要依赖前面两者
      最后到web服务,因为它需要依赖前面三者

    • 为什么注册中心不需要上报机器信息到服务治理中心?
      按道理是需要的,但是这里怕麻烦,没有做。(我在想,先有注册中心还是先有服务治理中心?小纠结,,,后续看看怎么优化)

    • 如何检测机器状态的?
      通过客户端定时发送心跳信息到服务治理中心。
      可能有人会问,为什么是客户端主动发送心跳,而不是服务端主动检测呢?
      其实两种方法都可以实现,但是客户端主动发送心跳可以减少服务端的消耗,并且实现起来简单。

    • 为什么重启thrift服务后,web调用thrift接口会报错?
      首先thrift服务重启,那么第一次的连接肯定失效了,其次第一版非常粗糙,重试机制都没做。。。,所以会发生上面的情况。

    • 使用注册中心和服务治理有什么优势?
      从这个小demo都可以看出来优势,首先,以前没有RC(注册中心简称)和SG(服务治理简称)的时候,web每次连接thrift都需要手动改一下ip(因为每次重启电脑后,IP都有可能会变),如果有N个客户端要连thrift,那么就需要改N个客户端的代码,非常的不灵活。有了RC和SG后,所有服务只需要记住RC和SG的IP,就能够拿到其它服务的IP。当然了还有很多很多优势,例如限流、熔断、鉴权等等。

  • 总结与改进
    每次写完一个小demo,都会去思考,还有什么能改进的。就好比一个小公司成长为大公司,期间的架构肯定是从最简单的演化到最复杂的。例如,以前的网站架构都非常简单,使用linux+mysql+apache+php,就可以很快的搭建出来,因为一开始流量都很小,linux机器单机,mysql机器单机,还可能不是多台机器,而是一台机器,包干所有!然后演化到现在,流量大了,场景也复杂了,什么分布式啊,集群啊,统统干上了。但是万变不离其宗,先从它祖宗十八代研究起,把它翻个底朝天不是更有趣吗?

    • 通过这四个服务,发现thrift的代码非常的重复
      例如服务启动的代码,基本每个服务都有一个ThriftServerBean,并且都干着同样一件事。所以,第一想法,抽出来!

      @Component
      public class ThriftServerBean implements FactoryBean<ThriftServerBean>, InitializingBean {
      
          private TServer tServer;
          @Value("${local.port}")
          private Integer port;
          @Value("${local.appKey}")
          private String appKey;
          @Autowired
          private TRegistCenterImpl tRegistCenter;
      
          @Override
          public ThriftServerBean getObject() throws Exception {
              return new ThriftServerBean();
          }
      
          @Override
          public Class<?> getObjectType() {
              return ThriftServerBean.class;
          }
      
          @Override
          public void afterPropertiesSet() throws Exception {
              TProcessor tProcessor = new TRegistCenter.Processor<TRegistCenter.Iface>(tRegistCenter);
      
              TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(port);
      
              TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
      
              TNonblockingServer.Args tArgs = new TNonblockingServer.Args(serverTransport);
      
              tArgs.processor(tProcessor);
              tArgs.protocolFactory(protocolFactory);
      
              tServer = new TNonblockingServer(tArgs);
              System.out.println("[info] RegistCenter bootup successful -> " + NetWorkUtil.getInet4Address() + ":" + port);
              new Thread(()-> tServer.serve()).start();
          }
      }
      

      再有就是ThriftClientConfig,也是极为重复,抽出来!

      所以,很有必要对thrift进行封装,基于我们的demo(业务),进行二次开发

    • 都可以将什么抽出来呢?
      首先,我们要明白一件事,基础设施是为了减轻业务负担而存在的,所以目标肯定是,thrift服务和web服务就只干一件事,实现自己的业务逻辑,不需要管什么连接啊,注册啊,服务如何如何启动啊等等。
      那么谁来做呢?那肯定就是通信层做了,例如A调用B的接口的时候,发生了一次远程调用,也就是网络调用,那么我们是不是可以用AOP,在A调B接口的前后做一些事情呢?所以又用到了spring的知识。

    • 最后总结一下服务发现与治理(下)需要做的事情

      • 基于thrift进行二次开发,目标是让每个服务专注于业务逻辑,而不需要管通信层的事情(下篇文章就干货满满哦,就不是demo级别的了)。
原创文章 257 获赞 277 访问量 69万+

猜你喜欢

转载自blog.csdn.net/qq_18297675/article/details/103396396