1. 首页
  2. >
  3. 技术专题
  4. >
  5. SpringCloud

SpringCloud2020替换Netflix套件实践一

SpringCloud2020替换Netflix套件实践一

Spring Cloud 2020版已经发布了,因为网飞Netflix套件进入维护期,替代方案也出来了,本着“就新不就旧”的原则,个人的知识结构也要更新,所有就有了下面的内容。

按照官方给出的推荐替代品,主要是:网关由Gateway替换Zuul,断路器由Resilience4j和Sentinel替代Hystrix,负载均衡LoadBalance替换Ribbon。

还有例如从Feign衍生出来的OpenFeign等,替换注册中心Eureka的Nacos、Consul等。

本文主要是想基于Spring Cloud 2020一些新的组件+Docker,组建一个轻量级的微服务Demo,总结一下学习成果,也适用于一些小型的微服务系统,简单开发,简单部署。

要是您的系统有千儿八百个微服务,就没必要看了。

以下选型:

1、注册中心依然用Eureka。选这个原因很简单,就是简单,且够用。

2、REST客户端OpenFeign。

3、负载均衡Spring Cloud LoadBalance。

4、断路器Resilience4j。

5、网关Spring Cloud Gateway。

6、部署Docker+脚本。

服务也简单,毕竟是学习用,没有上集群(Eureka集群配置《Eureka集群配置》),没有配置中心(个人感觉,小型系统,上配置中心麻烦大于好处),不涉及数据库、Redis、MQ等(这些内容以前文章有写)。只有4个工程:

SpringCloud2020替换Netflix套件实践一

b-server通过OpenFeign调用a-server,内容都很简单,主要是看这些组件的配置和使用。

只涉及一些核心用法和配置参数,更多更详细的可以参看别的资料和官方文档。


Eureka Server&Client

我说Eureka简单,就体现在下面:

SpringCloud2020替换Netflix套件实践一

SpringCloud2020替换Netflix套件实践一

SpringCloud2020替换Netflix套件实践一

接着是微服务的配置:

SpringCloud2020替换Netflix套件实践一

多了一个用于监控的actuator,有了这个,在Eureka控制台上点击注册的服务,就能看到一些监控信息。

SpringCloud2020替换Netflix套件实践一

SpringCloud2020替换Netflix套件实践一

至此,我们的微服务就能在Eureka上注册了。

Docker打包&发布

将工程打包成jar,同级目录编写Dockerfile文件,内容:

FROM openjdk:8 VOLUME /tmp ADD a-server.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

如图:

SpringCloud2020替换Netflix套件实践一

在此目录下执行构建命令:

docker build -t leo.org/aserver .

别忽略了最后一个“.”

镜像就有了:

SpringCloud2020替换Netflix套件实践一

接着依次运行就可以了,但是问题也就来了。

通过Docker容器运行的微服务去Eureka注册的时候用的不是IP,是容器ID。当微服务跨容器,跨宿主机时,服务间OpenFeign是无法调用的。倒是可以用host来转一下,把容器ID与IP对应起来,但是N多微服务都要维护host,太麻烦,新增容器都要同步更新,虽然可以将容器的host挂载到宿主机的一个文件内,也是麻烦。如果上档次一些,用k8s、Docker Swarm等倒是没这些问题。

只是我本次就想简单一点,轻量化,所以才有了下面的解决方案:

1、使用IP注册

在所有的微服务配置文件里增加

eureka.instance.prefer-ip-address=true

表示微服务向Eureka注册时候使用IP。

注意,这里说的是使用IP,而不是显示IP,现在Eureka控制台上显示的还是容器ID。

如果想显示IP,则配置

eureka.instance.instance-id:${eureka.instance.ip-address}:${server.port}

但是因为我们使用了Docker,其注册的IP是Docker的内部IP,17*,OpenFeign照样访问不了,就有了下面的处理方案。

2、注册宿主机IP

eureka.instance.ip-address=宿主机IP

这样注册在Eureka,并提供给其他服务的IP就不是Docker内部的IP,而是宿主机对外提供服务的IP了。

但如果将宿主机IP写死在配置文件里,一个微服务生成一个镜像,当我们要基于此镜像生成多个容器运行的时候,一般会部署在多个宿主机上,这个写死的IP就很不合时宜了,所以改成用命令行赋值的办法:

docker run -d --name aserver1 --expose=1001 -p 1001:1001 -e "EUREKA_INSTANCE_IP-ADDRESS=192.168.31.247" -e "SERVER_PORT=1001" -e "INFO_APP_NAME=aserver1" leo.org/aserver docker run -d --name aserver2 --expose=1002 -p 1002:1002 -e "EUREKA_INSTANCE_IP-ADDRESS=192.168.31.248" -e "SERVER_PORT=1002" -e "INFO_APP_NAME=aserver2" leo.org/aserver

上面两行命令,就分别在247、248两台宿主机上根据aserver镜像部署了名为aserver1、aserver2两个容器进行负载。

以上我们可以通过脚本命令从git或svn上获取最新代码,编译打成jar,与Dockerfile配合生成镜像,通过命令生成容器,这一系列的命令都可以做成sh脚本,如果再搭配Jenkins,就可以实现自动构建、部署了。


预告:第二篇写OpenFeign和Gateway,第三篇写Resilience4j的CircuitBreaker、Bulkhead、RateLimiter