首页 > 经验记录 > java > 高可用的服务注册中心:Eureka 集群搭建 , 并使用Spring Security 为 Eureka 增加 Basic 安全认证机制

高可用的服务注册中心:Eureka 集群搭建 , 并使用Spring Security 为 Eureka 增加 Basic 安全认证机制

上一篇 Spring Cloud 项目的搭建文章 : 链接

 

再说下我的版本号 , 用的比较新:

 

Spring Boot 2.0.5 RELEASE

Spring Cloud Finchley.SR3

项目管理工具: gradle


进入正题:

从之前的项目构造来看,RPC虽然是实现了,但是调用的链接确是写死在代码中的,比较丑陋。

要是提供服务的地址突然换了,那这边消费者直接雪崩,只能更改代码重新部署。而且无法实现负载均衡,这在一个微服务架构中是很不合理的。

要解决这问题,作为服务消费者,必须要有一个牛逼的服务发现机制。

Spring Cloud 就提供了多种服务发现组件的支持。Eureka、ZooKeeper 等,我这就用 Eureka 了, 在 Spring Cloud 这个生态圈里Eureka是比较流行的。

Eureka是网飞(Netflix)开源的服务发现组件。有Server和Client两部分,按需使用就行,我这就使用他们来构建一个高可用的服务注册中心。

 

我先把之前父模块的的Mybatis、mysql依赖给去了,放到了实际的微服务中(user/movie)。因为Eureka服务不需要这几个依赖,要是加载了mysql依赖会自动连接mysql,不加mysql的配置就会报一堆错误。

 

既然 Eureka 也是个服务,那当然也得在父模块下创建一个Eureka子模块。和其余的模块创建相同,没什么好说的。

给 Eureka 服务注册中心模块加上这个 Eureka Server 依赖

compile(“org.springframework.cloud:spring-cloud-starter-netflix-eureka-server“)

然后在 Eureka 服务的入口 java 文件上加上该注解 @EnableEurekaServer , 这个Application就是完全体了。

 

此时可以在网页里通过 ip:port 来访问页面,可以得知注册中心的状态、多少服务链接到本机。

 

Eureka Server 端写完后,需要注册的服务则需要导入Eureka的Client依赖,就是这个:

compile(“org.springframework.cloud:spring-cloud-starter-netflix-eureka-client“)

然后只要在yml文件中配置好要连接的服务注册中心的地址就完事了,其实此时一个服务注册发现功能已经可以完成了。

但是还不够,需要考虑到若是 Eureka Server 端突然宕掉,那么整个系统就会出问题。

客户端虽然会有相应的缓存(服务注册时会将Server端储存的数据拿到本地缓存),但是在此时若是其他的服务发生变更,靠缓存中的信息去请求就不正确了。

 

所以,想要高可用的一个服务注册中心,则需要搞一个集群。宕掉一个,还有另外的,这样容错率将大大提高。

其实Eureka搞集群非常简单。不过是开启两个实例,A实例注册进B实例,B实例注册进入A实例而已。

只需要使用两种不同的配置即可。(你要是想开五个就是五个不同的配置,看着加就完事了)

像我这样,我这是写在一个yml文件里了,用“—”来隔开,要是配置比较多是可以另起一个文件的,就叫application-xxx.yml。

可以使用 –spring.profiles.active=xxx 来启动不同的服务。

(这里有部分Security的配置,下面就讲)

在IDEA里边,可以使用这种方式来启动不同的实例:

集群也搭完了,启动第一个Eureka Server时可能会出点连接错误,不过不影响启动,这是因为第二个Server还没启动起来,而配置里需要它注册进去导致的,第二个启动起来后就没错误了。

你要是一下子就从网页进去看Eureka的状态,可能会出现红色粗体的:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

这个是Eureka的自我保护机制导致的。Eureka Server和Client之间每隔一段时间会进行一次心跳通信,告诉Server,Client还活着。要是某一段时间Server感觉自己这边少了几个心跳就会出这问题,只要不是真的你服务宕掉了,过一会就好了。

 

配置完毕后,客户端也只需要在配置文件中写两个链接就行,用逗号隔开。其实写一个也可以,因为Eureka集群会自动同步其他Eureka的注册信息。但还是推荐写俩,就是怕某些极端情况发生。

 

此时集群已经搭建完毕。客户端也可以连接得上,但是,这些端口就这样暴露出来也是很不科学的。攻击者可以轻易地得到你的服务信息。

最好的,当然还是加个验证啦!用户名密码这种验证永远不过时哈。

搭建完集群后,用 Spring Security 为 Eureka 增加 Basic 安全认证就很不错了!

只需要在 Eureka Server这边添加 Spring Security 的依赖就够了,Client端不用。

compile(“org.springframework.boot:spring-boot-starter-security“)

 

添加Security的依赖后就会自动开启验证,不用配置。用户名和密码的设定就像上边文件一样,只需要这样就行。

 

配置完用户名和密码后,连接Eureka Server自然就需要用到这些用户名和密码。

本来连接Server的的URL:   http://ip:port/eureka/

现在连接Server的的URL:   http://username:password@ip:port/eureka/

就算是从网页查看状态,也需要输入用户名和密码了哦。

 

Client端最终配置文件如下(反正配置都长得差不多,我这就放其中一个服务的文件就行了):

 

这样,其实应该就完事了,但是,在2.x版本的 Spring Security 中,引入依赖后,自动开启CSRF安全认证。

任何一次服务请求默认都需要CSRF 的token , 而我区区一个小Client,哪里来的这种东西。就是Eureka Server 自注册都会挂掉。

那么还是要让 Security 的CSRF拦截自动忽略掉注册Eureka的链接比较好。

在 Eureka Server 端增加这么一个配置类:

这样子去除 /eureka/  这个连接的 CSRF 效验。就都可以连接上了。

 

OK 整体 Eureka 注册中心都搭建完毕了。并且实现了集群高可用和安全策略,比较完善。

 

服务之间的调用在做一点点微小的改进:

 

通过 DiscoveryClient 这个类,可以获取到对应服务的信息,这里我便是用 movie 服务获取到了user 服务的 url  来进行的调用。

当然,就算是这样,也不是那么的方便,关于feign声明式调用之后也会写篇文章的。

 

我的项目地址: github


1 COMMENT

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00