spring-cloud-zuul 结合Apollo使用实战
- 项目背景
- Apollo配置
- Apollo简介
- Apollo操作
- 本地应用配置
- 应用部署K8s配置
- 结语
项目背景
目前,我司的spring-cloud-zuul 服务采用传统的静态配置方法,针对不同环境写不同的yml配置文件,运行时无法动态修改,每次新增服务,都要在zuul中增加服务映射,重启服务。为了实现不需停服增加服务映射,引入apollo配置。
Apollo配置
Apollo简介
Apollo(阿波罗)是写成框架部门研发的开源配置管理中心,能够集中化管理应用各不同环境、不同集群的配置,配置修改后能够实时的推送到应用端,并且具备规范的权限、流程治理等特性。
Apollo支持4个维度管理Key-Value格式的配置:application(应用)、environment(环境)、cluster(集群)、namespace(命名空间)
Apollo操作
- 登录apollo
- 填写项目信息
- 新增命名空间
创建项目后,apollo会默认在所有环境都创建一个application的命名空间,类型为properties;由于项目中使用的配置文件是yml类型的,方便直接拷贝配置,可以新建一个yml类型的命名空间。
点击左下角的“添加Namespace”,新建一个名为“faceBootStrap.yml”的命名空间。创建完成后,每一个环境都会新增一个命名空间。 - 配置编辑与发布
选择需要配置的环境,这里以DEV为例,将本地bootstrap-dev.yml内容拷贝过来,完成后点击发布,即完成应用的dev环境配置。
本地应用配置
- 配置apollo客户端依赖
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo-client-version}</version>
</dependency>
- 主入口程序
@Configuration
@EnableApolloConfig("faceBootStrap.yml")
public class SsoWsGatewayApp extends WebSecurityConfigurerAdapter {
}
- 配置文件配置
删除不同环境的配置文件,只需一个bootstrap.yml配置文件,内容如下:
app:
id: face-recognize #指定应用id
apollo:
bootstrap:
enabled: true
namespaces: faceBootStrap.yml #指定命名空间
eagerLoad:
enabled: false
- 动态路由
创建zuul路由规则刷新类ZuulProxyRefresher,具体代码如下。实现在apollo配置中增加新的服务映射,无需重启zuul。
@Component
public class ZuulProxyRefresher implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Autowired
private RouteLocator routeLocator;
@ApolloConfigChangeListener(value = "faceBootStrap.yml")
public void onChange(ConfigChangeEvent changeEvent) {
boolean zuulProxyChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changedKey.startsWith("zuul.")) {
zuulProxyChanged = true;
break;
}
}
if (zuulProxyChanged) {
refreshZuulProxy(changeEvent);
}
}
private void refreshZuulProxy(ConfigChangeEvent changeEvent) {
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
this.applicationContext.publishEvent(new RoutesRefreshedEvent(routeLocator));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
- 本地环境变量配置
本地启动时,配置两个环境变量,JAVA_TOOL_OPTIONS 配置apollo的configService的url。 env 指定使用apollo的DEV环境上的配置。
通过apollo配置和本地应用配置,完成了zuul服务在apollo的配置,启动相关服务,可以正常访问,在apollo配置上动态新增服务也可以直接访问新服务。
应用部署K8s配置
由于apollo的环境变量env在K8s的上被占用,导致直接采用env做apollo的环境变量部署到k8s会出错。解决方法如下,自定义环境变量和配置加载类,。
- K8s环境变量配置
- K8s自定义配置加载类
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
public static final int DEFAULT_ORDER = ConfigFileApplicationListener.DEFAULT_ORDER + 1;
private int order = DEFAULT_ORDER;
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String property = environment.getProperty("apolloenv");
System.setProperty("env", property);
}
@Override
public int getOrder() {
return order;
}
}
- K8s环境变量配置
env:
- name: apolloenv
value: DEV
- name: JAVA_TOOL_OPTIONS
value: -Dapollo.configService=https://apollodev.utyun.com
结语
通过以上步骤,通过zuul与apollo的结合,实现zuul服务配置的动态修改。