这可能是讲分布式系统最到位的一篇文章( 三 )

 
importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importio.netty.bootstrap.Bootstrap;importio.netty.channel.Channel;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelOption;importio.netty.channel.ChannelPipeline;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.nio.NioSocketChannel;importio.netty.handler.codec.LengthFieldBasedFrameDecoder;importio.netty.handler.codec.LengthFieldPrepender;importio.netty.handler.codec.bytes.ByteArrayDecoder;importio.netty.handler.codec.bytes.ByteArrayEncoder;importio.netty.util.concurrent.Future;/***nettytcp客户端*@authorv_wangshiyu**/publicclassNettyTcpClient{privatestaticfinalLoggerlog=LoggerFactory.getLogger(NettyTcpClient.class);privateStringhost;privateintport;privateBootstrapbootstrap;privateChannelchannel;privateEventLoopGroupgroup;publicNettyTcpClient(Stringhost,intport){bootstrap=getBootstrap();channel=getChannel(host,port);this.host=host;this.port=port;}publicStringgetHost(){returnhost;}publicintgetPort(){returnport;}/***初始化Bootstrap*@return*/publicfinalBootstrapgetBootstrap(){group=newNioEventLoopGroup();Bootstrapb=newBootstrap();b.group(group).channel(NioSocketChannel.class);b.handler(newChannelInitializer<Channel>(){@OverrideprotectedvoidinitChannel(Channelch)throwsException{ChannelPipelinepipeline=ch.pipeline();//pipeline.addLast(newEncoder());//pipeline.addLast(newDecoder());pipeline.addLast("frameDecoder",newLengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));pipeline.addLast("frameEncoder",newLengthFieldPrepender(4));pipeline.addLast("decoder",newByteArrayDecoder());pipeline.addLast("encoder",newByteArrayEncoder());pipeline.addLast("handler",newTcpClientHandler());}});b.option(ChannelOption.SO_KEEPALIVE,true);returnb;}/***连接,获取Channel*@paramhost*@paramport*@return*/publicfinalChannelgetChannel(Stringhost,intport){Channelchannel=null;try{channel=bootstrap.connect(host,port).sync().channel();returnchannel;}catch(Exceptione){log.info(String.format("connectServer(IP[%s],PORT[%s])fail!",host,port));returnnull;}}/***发送消息*@parammsg*@throwsException*/publicbooleansendMsg(Objectmsg)throwsException{if(channel!=null){channel.writeAndFlush(msg).sync();log.debug("msgflushsuccess");returntrue;}else{log.debug("msgflushfail,connectisnull");returnfalse;}}/***连接断开*并且释放资源*@return*/publicbooleandisconnectConnect(){//channel.close().awaitUninterruptibly();Future<?>future=group.shutdownGracefully();//shutdownGracefully释放所有资源,并且关闭所有当前正在使用的channelfuture.syncUninterruptibly();returntrue;}}importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.SimpleChannelInboundHandler;/***客户端处理器*/publicclassTcpClientHandlerextendsSimpleChannelInboundHandler<Object>{privatestaticfinalLoggerlog=LoggerFactory.getLogger(TcpClientHandler.class);@OverrideprotectedvoidchannelRead0(ChannelHandlerContextctx,Objectmsg)throwsException{byte[]data=https://www.isolves.com/it/cxkf/jiagou/2020-02-22/(byte[])msg;}} 
说到通讯就不能不说协议,通信时所遵守的规则,访问什么,传输的格式等都属于协议 。
 
作为一个开发人员,应该都了解 TCP/IP 协议,它是一个网络通信模型,以及一整套网络传输协议家族,是互联网的基础通信架构 。
 
也都应该用过 Http(超文本传输协议),Web 服务器传输超文本到本地浏览器的传送协议,该协议建立在 TCP/IP 协议之上 。分布式服务框架服务间的调用也会规定协议 。
 
为了支持不同场景,分布式服务框架会存在多种协议,如 Dubbo 就支持 7 种协议:Dubbo 协议(默认),RMI 协议,Hessian协议,HTTP 协议,WebService 协议,Thrift 协议,Memcached 协议,redis 协议每种协议应对的场景不尽相同,具体场景具体对待 。
 
服务路由
 
分布式服务上线时都是集群组网部署,集群中会存在某个服务的多实例,消费者如何从服务列表中选择合适的服务提供者进行调用,这就涉及到服务路由 。分布式服务框架需要能够满足用户灵活的路由需求 。
 
透明化路由 
很多开源的 RPC 框架调用者需要配置服务提供者的地址信息,尽管可以通过读取数据库的服务地址列表等方式避免硬编码地址信息,但是消费者依然要感知服务提供者的地址信息,这违反了透明化路由原则 。
 
基于服务注册中心的服务订阅发布,消费者通过主动查询和被动通知的方式获取服务提供者的地址信息,而不再需要通过硬编码方式得到提供者的地址信息 。
 
只需要知道当前系统发布了那些服务,而不需要知道服务具体存在于什么位置,这就是透明化路由 。 


推荐阅读