Spring Cloud Config (2)
前篇博文讲解了Spring Cloud Config的入门部分,虽然搭建起来了一整套服务配置框架(配置服务、客户端、Git仓库),但是如果要达到生产使用级别还存在着3个缺陷:
1,config-server单结点,需要高可用性。
2,config-server包含全系统的配置,安全需要加固
3,config-client配置是启动加载的,不能刷新
本篇博文就针对这3个缺陷给出解决方案。
本期项目地址:
Eureka:https://github.com/yejingtao/forblog/tree/master/demo-eureka-register
Config-server:https://github.com/yejingtao/forblog/tree/master/demo2-config-server
Config-client:https://github.com/yejingtao/forblog/tree/master/demo2-config-client
安全验证:
pom 添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
服务端配置:
security:
user:
name: user
password: ${CONFIG_SERVICE_PASSWORD}
客户端配置:
spring.cloud.config.username=user
spring.cloud.config.password=${CONFIG_SERVICE_PASSWORD}
以启动参数的方式,动态传入密码,是为了防止jar包或文件的传播而造成更多的人知道密码。
验证下:
当要访问config-server的时候是需要用户认证的
只要我们config-server和config-client使用同样的CONFIG_SERVICE_PASSWORD就可以搭建起来一个相对安全的环境了。
高可用性:
我们将ConfigServer作为一个普通的微服务应用,纳入Eureka的服务治理体系中,这样我们的微服务应用就可以通过配置中心的服务名来获取配置信息,同一个服务名背后可以被多个微服务来支撑。
客户端和服务端项目都需要依赖Eureka,Application启动程序里都需要@EnableEurekaClient注解,yml或者properties参数配置里都需要给定eureka的服务地址,这些此处一笔带过,详见代码。
重点讲下客户端启动参数核心变动:
将
spring.cloud.config.uri=http://localhost:8001
改为
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
修改之前是直接配置了config-server的服务地址,修改之后是打开服务发现机制,指定config-server的微服务名称,去eureka上获取config-server的服务地址。
参数刷新:
前一篇博文我们已经知道config-server的刷新是不需要我们操心的,自己会去git上refresh。现在的问题时config-client的配置是启动加载的,运行中git上修改之后client怎么刷新配置?这里我们需要引入Spring Cloud Actuator,配置和程序不需要任何修改。一旦Git上参数配置修改后通过http post请求http://client-IP:Port/refresh便可以刷新config-client的配置参数。
到目前位置,看似前面遗留的3个优化问题目前已经解决了,但是actuator的引入又带来了新的问题:密码泄露。
请求http://client-IP:Port/env
要解决密码泄露问题又有2个方案:
真正生产环境我们微服务地址是不会暴露给客户端的,边缘服务之前会架一套Spring Cloud Zuul来做路由分发,通过zuul的filter功能我可以限制外部直接访问我微服务结点的/env,开发人员如果需要定位问题可以自己找到具体的微服务结点通过结点本身的ip和端口去访问/env。
关于Zuul的原理和实例代码前面博文有讲过,此处忽略。
就算我的password被泄露了,我可以给我Git仓库里的敏感配置信息(数据库密码、加密算法等)加密吧,这样就算拿到了我的配置文件也没任何意义。
1,首先给config-server配置里添加一个密钥encrypt.key=configtest
2,然后启动config-server,通过/encrypt 对敏感内容加密。例如我的数据库密码是mima123,那么通过http://config-server:port/encrypt –d mima123 加密后密码是682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
3,然后用加密后的密文替换Git仓库中的明文,记得要加一个{cipher}前缀,告知连上来的config-server这个是密文需要解密。
OK,安全问题也解决了,再回头看我们的整个设计还是不够完美,每次git仓库中更新了配置需要config-client端一个个的refresh。如果微服务结点不多的情况下还可以接受,但是对于几十个上百个微服务结点如果要手工每个refresh一遍先不说工作量有多少,一旦粗心大意导致配置不同步那可能就是灾难性的问题。
当然作为程序员没有什么解决不了的,我们可以开发一个程序,把需要refresh的地址维护起来,然后通过一键式触发搞定这个问题,但是微服务的结点在治理过程中是变动的(random port就是个案例),我们维护的列表也再不断地变更,维护这个列表也会变得很吃力。
所以,Spring又推出来一个组件解决这个问题Spring Cloud Bus,我们下回再说。
还没有评论,来说两句吧...