美文网首页程序员@IT·互联网
微服务系统架构系列4——服务发现java

微服务系统架构系列4——服务发现java

作者: 窝牛狂奔 | 来源:发表于2017-05-22 19:41 被阅读0次

前面我们讲了node.js来做网关,把前端的请求进行转发。但实际上,请求一个统一的地址,然后由服务器进行转发这种模式是有很大的缺陷的,前端因为其特殊性,只能这么做,但是如果在后端,我们也这样干,实际上我们就相当于做了个ESB。当请求量过大时,ESB服务器(提供服务发现和请求转发的服务器)就成为了瓶颈,用于转发服务的服务器,总有一天会爆掉,一旦爆掉,那就是全站事故,这是一件很恐怖的事情。事实上,我们公司最早的服务框架也是ESB的,请求量大了会出现各种各样的问题,所以现在新的服务框架也已经转为点对点的模式了。


我们总结一下java的soa client需要做的几件事情:

1、提供一个client,client运行在调用端。

2、client里能拿到zookeeper维护的服务地址,并且缓存起来。

3、当服务地址变化的时候(有服务挂掉了),client要更新自己的服务地址缓存。

4、client能将请求post服务地址。并将返回的内容反序列化为对象(java对象或.net对象)。

那么,我们的思路就出来了:

1、client是一个单利的。

2、client初始化的时候,通过zookeeper客户端拿到服务地址,并缓存。

3、client需要通过zookeeper时刻监听服务地址的变化情况。

4、client将Request对象封装为http请求。

5、client通过HttpClient将请求发出去(我翻了我们公司的源码,也是用的HttpClient来发送请求)

6、client将返回内容转换为Response对象

环境准备

1、我用的是idea

2、HttpClient如果大家想详细了解下它的特性和使用方法,可以看下网上的博客。例如:http://blog.csdn.net/wangpeng047/article/details/19624529

3、zookeeper的java客户端

4、序列化反序列化的工具gson

实现服务端

定义Request和Response

请求类GreetRequestType.java

username属性,用来传需要打招呼的人的名字

返回类GreetResponseType.java

greetInfo属性,用来返回打招呼的内容

然后我们实现服务端,跟HelloService相似,我们在Application

里加上GreetService服务,不过method是Post。服务的功能根据GreetRequestType

里的username字段,拼打招呼的内容,并赋值给greetInfo。比如输入cqin,返回Hello cqin。

Application如何实现服务的注册,我们在《微服务系统架构系列2——服务注册》已经讲过了。

通过springboot,在端口8080和8082分别启动springboot。具体启动方式,同样见《微服务系统架构系列2——服务注册》,这里就不重复写了。

然后我们用postman手动post请求到8080和8082,可以看到如下访问:

同时,我们通过zkCli.cmd连接到zookeeper的客户端,可以看到/registry/GreetService下有两个节点

这个说明,我们的服务端实现完成。

实现ServiceClientBase

ServiceClientBase主要分两个功能, 一个是zookeeper相关的,一个是httpclient相关的。

Zookeeper相关的包括服务地址的发现和监听。Httpclient相关的,主要是发送请求到服务端,并将请求转换为Response。

服务地址的发现和监听,监听的代码比较粗暴,我们是直接把服务里所有的节点删了节点 , 然后再加。这个如果在生产上,可以自己改进下监听的事件。

请求发送

客户端代码

调用代码

我们用junit,每隔1秒发送一个请求,连续发送100次。

实验结果

首先通过8080和8082端口启动GreetService。

然后通过UnitTest,启动HelloServiceClientTest。

此时,会随机访问8080和8082这两个端口,并返回Hello cqin。

然后,我们停掉8082的sprintboot,模拟机器出问题的情况。

此时,再继续访问8082,client会报错。之所以会有这个报错,是因为从机器挂掉,到我们的zk客户端监听到变化事件是有一个很小的时间差的。所以,如果服务是异常挂掉,会有一小端时间的报错,我们没有办法。但如果是正常发布,我们有很多办法可以保证不会出现这报错,比如在zk里定义一个valid的属性,准备拉出的时候,先将valid设置为false,客户端发现valid为false,则不往集群发送请求,间隔5s后,再拉出集群。

然后,由于我们监听过NodeChildrenChanged事件,接收到这个事件了之后, 我们会进行地址的更新。所以,此时,客户端只会访问到8080这个端口,报错不再发生。

然后,我们重新启动8082端口的springboot,等客户端再次接受到NodeChildrenChanged

事件之后,客户端会再次进行地址更新,之后,就可以访问到8082端口。

总结

我们基本实现了后台代码的服务发现,并且提供了一个client。这个client,能够自动发现服务的变化,缓存服务的地址,并帮助客户端将Requet序列化成json之后,通过HttpClient,post到服务端。

至此,服务端只需要定义一个java的Request文件和一个Response文件,并实现服务逻辑。客户端只需要调用HelloServiceClient.getInstance().greetService(request);就可以拿到服务的返回。

相关文章

网友评论

    本文标题:微服务系统架构系列4——服务发现java

    本文链接:https://www.haomeiwen.com/subject/sbdhattx.html