Spring Cloud 实现多服务器部署

1,542 阅读6分钟

Spring Cloud 实现多服务器部署

前景摘要: 项目要求实现 ,微服务部署在多个服务器,这在分布式架构,实现RPC本来是一个十分常规的操作,但是在操作过程共还是遇到了一些问题,特此记录.

配置文件内容

####不同服务器发布####   
eureka:
    instance:
      # ip 地址优先
      prefer-ip-address: true
      # 服务实例的id,就展示在Eureka的管理界面
      instance_id: ${spring.cloud.client.ip-address}-${server.port}
   client:
      service-url:
         # 对于不同服务器,就要注册到对应地址的注册中心
         defaultZone: http://192.168.1.11:8001/eureka/

###同一台服务器发布##
eureka:
   instance:
      hostname: localhost
   client:
     service-url:
       # 同一台服务器 注册中心就在localhost
       defaultZone: http://${eureka.instance.hostname}:8001/eureka/

Eureaka 界面

​ 对于同一台服务器来讲,服务注册到Eureka注册中心,很容易实现,只要写好 eureka.instance.hostnamelocalhost,然后把defaultZone 指向localhost即可.

​ 对于不同的服务器,则需要配置prdfer-ip-address的值为true,再把defaultZone指向eureka所在地址即可.

实现结果

​ 配置完成后部署成功,如果能够在Eureka的管理界面,看到所启动服务已经注册到注册中心,表示配置成功.

有坑

文件的配置实现的很简单.但是还是不可避免的踩到了坑.

1. 安全组规则

在配置完成后,也已经观察到了.服务成功注册到注册中心,但是访问对应的接口还是不能访问到,最终发现是阿里云服务器安全组规则的坑.

笔者部署的服务器需要访问到某个端口,从而访问到数据库的数据,但是当时公司的服务器为了保证数据库安全,这些端口是不对外开放的,所以导致计算微服务配置成功可还是不能正常显示.所以如果使用的是阿里云的服务器,一定好设置好安全组.

新发现

之所以能发现是阿里云安全组的问题,其实也是一个偶然的操作.在看到服务已经成功注册到Eureka之后,经过百般尝试怎么都不行,结果扔在测试服务器给搞定了.扔在生产环境就搞不定.经过大哥提醒有可能是安全组的问题.然后去看安全组,发现新服务所在服务器使用的是测试环境的安全组,于是我尝试了第一种解决方案

  • 把所有正式环境的安全组开放的端口,在测试环境也全部开放.

结果,还是不成功.于是我就萌生了.第二种想法

  • 我为啥不直接用正式环境的安全组呢? 于是新服务器使用正式环境的安全组.

结果,成功了! 但是测试环境上的新服务又失效了.Emm...

要的结果是 2:1,而不是1:1;到现在为止的结论就是使用正式环境的安全组,正式环境就OK,使用测试环境的安全组,就不行.

  • 然后我的另一个野鸡操作又来了, 我在正式环境的安全组把测试环境开放的端口都开了(不建议,只是当时要搞清楚问题,临时这么做.测试完就还原了).

结果又是失败.

  • 突然想起一个问题.在测试环境 ,服务和数据库集群是同一个服务器,和正式生产环境是服务和数据库分别使用独立的服务器.也就是说 我得考虑正式数据库环境的安全组.

在新服务器使用测试安全组的情况下,开放正式数据库的安全组端口后.结果就成功了.

于是,结论来了.新服务器必须在使用生产环境的安全组或者 使用测试环境安全组的同时开放数据库端口,才能实现多服务器部署.而在测试服务器上部署是两个安全组都可以的.

原因是: 测试服务器的数据库的端口是开放的,而正式环境的数据库端口需要在数据库所在服务器开放.

测试服务器 也测试过了, 如果把测试服务器对应的数据库的端口关闭后,原本能成功访问的数据也获取不到了.

现在的情况是: 如果我要在正式服务器上部署,就必须开放数据库端口,这显然不是我想要的.毕竟之前就不开放,显然是为了能安全.

等等,之前不开放 ?? 那之前的数据库是怎么访问的? 还有上面 新服务器导入了生产环境的安全组,但是并没有开放数据库的端口,它怎么就又能部署成功,数据也访问成功呢?

难道说,如果说我多个服务器之间只要共用同一个安全组规则,那共用的这几个服务器就可以不受安全组的约束吗?答案是肯定的.

至于说iptables 规则如何配置,下回分解.

2. Eureka

先说结论: 同一个服务下,有多个的实例instance,不正常的实例会影响到正常的实例.

这个界面上显示的实例,有可能是已经失效的服务,但是Eureka中心 还是会显示出来;

那如何去处理掉无效的呢?

  1. host:port/eureka/apps/{appID}/{instanceID}/status?value=DOWN

value 可以是 DOWN 也可以是UP

DOWN 就是无效的时候,让其下线,UP 就是当服务注册不上的时候 ,让其上线.

要用PUT 请求,而不是常用的GET或者POST请求

  1. host:port/eureka/apps/{appID}/{instanceID}/

该接口要使用DELETE请求.

浏览器是不支持,PUT或者DELETE请求的,所以需要借助类似postman的工具

实例部署还有一些需要注意的地方,摘抄自网络大佬:

  • 尽量不要使用 kill -9 pid 强制杀掉进程,而应该使用 kill pid 或者 kill -15 pid 关闭进程。使用 kill pid 或者 kill -15 pid 关闭进程之前,Eureka Client 会给 Eureka Server 请求删除自己,后续服务再次启动后会重新注册为 UP 状态。如果使用 kill -9 pid 强制杀掉进程,Eureka Client 没有办法注销自己,Eureka Server 就不知道该实例已下线,直到长时间收不到心跳才会删除该实例。如果在 Eureka Server 删除实例之前实例启动了,那么它的状态还是会保持 DOWN 状态。如果确实需要用到 kill -9 pid 强制杀掉进程,那么服务重启后需要再通过第一步的方式将实例状态设为 UP。
  • 服务启动后,需要等待并确认启动成功后,才可以开始部署下一台服务器。这里我们可以定时去请求 Spring Boot 提供的 actuator endpoint /health 接口,例如每隔 1 秒请求一次,直到接口可以正常访问,即可认为服务启动成功。

查看原文