尊重原创,本文转自:https://www.cnblogs.com/FlyAway2013/p/8811385.htmlhtml
前咱们项目,全部的配置基本都是经过本地properties 文件进行配置的,好比ip地址、端口、消息中间件和数据库链接的各类参数,当咱们须要切换环境或调整参数的时候,咱们必须手动的修改这些配置。若是只有一个配置文件还好,可是,若是有不少这样的配置文件,并且又分布式部署在多台机器,那么这样, 无疑是很是低效并且容易出错的。java
咱们当前的项目,大都是分布式部署的项目,机器多,配置项更是繁多,所以,咱们颇有必要引入一个配置中心。mysql
各开源配置中心对比矩阵以下:git
在对比了各家的开源产品以后,咱们选用了携程的apollo : https://github.com/ctripcorp/apollogithub
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,可以集中化管理应用不一样环境、不一样集群的配置,配置修改后可以实时推送到应用端,而且具有规范的权限、流程治理等特性,适用于微服务配置管理场景。redis
服务端基于Spring Boot和Spring Cloud开发,打包后能够直接运行,不须要额外安装Tomcat等应用容器。spring
Java客户端不依赖任何框架,可以运行于全部Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。sql
.Net客户端不依赖任何框架,可以运行于全部.Net运行时环境。数据库
上图简要描述了Apollo客户端的实现原理:json
将apollo-quick-start.zip 上传到某一个服务器, 做为配置中心, 解压, 修改sh脚本参数,
修改IP:
修改端口:
操做步骤:
1 修改apolloconfigdb.sql 的
# Config
# ------------------------------------------------------------
INSERT INTO `ServerConfig` (`Key`, `Cluster`, `Value`, `Comment`)
VALUES
('eureka.service.url', 'default', 'http://192.168.1.229:5998/eureka/', 'Eureka服务Url,多个service以英文逗号分隔'),
('namespace.lock.switch', 'default', 'false', '一次发布只能有一我的修改开关'),
('item.value.length.limit', 'default', '20000', 'item value最大长度限制'),
('config-service.cache.enabled', 'default', 'false', 'ConfigService是否开启缓存,开启后能提升性能,可是会增大内存消耗!'),
('item.key.length.limit', 'default', '128', 'item key 最大长度限制');
ip: 192.168.1.229
2 必定要先启动 cfg, 而后是 admin, 而后是 portal
admin必定要在 cfg启动成功 以后,
portal 必定要在 admin启动成功 以后,
D:\code\git\apollo\apollo-configservice\target>java -jar apollo-configservice-0.
10.0-SNAPSHOT.jar start -Dspring_datasource_username=ww
中止
./cfg/scripts/shutdown.sh ; ./adm/scripts/shutdown.sh ; ./ptl/scripts/shutdown.sh ;
./cfg/scripts/shutdown.sh ; ./cfg/scripts/startup.sh ; ./adm/scripts/shutdown.sh ; ./adm/scripts/startup.sh ; ./ptl/scripts/shutdown.sh ; ./ptl/scripts/startup.sh ;
java -Dapollo_profile=github -Dspring.datasource.url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8 -Dspring.datasource.username=root -Dspring.datasource.password=admin -jar cfg/apollo-configservice.jar
java -Dapollo_profile=github -Dspring.datasource.url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8 -Dspring.datasource.username=root -Dspring.datasource.password=admin -jar adm/apollo-adminservice.jar
java -Dapollo_profile=github,auth -Ddev_meta=http://localhost:5998/ -Dserver.port=5999 -Dspring.datasource.url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8 -Dspring.datasource.username=root -Dspring.datasource.password=admin -jar ptl/apollo-portal.jar
[root@VM228 apollo]# ./demo.sh start
==== starting service ====
Service logging file is ./service/apollo-service.log
Started [11050]
Waiting for config service startup....
Config service started. You may visit http://192.168.1.228:8080 for service status now!
Waiting for admin service startup...
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [11196]
Waiting for portal startup....
Portal started. You can visit http://192.168.1.228:8070 now!
系统出错,请重试或联系系统负责人 --- configdb 的serverconfig表 的: eureka.service.url 能够要重启。。
配置错误 。。。= http://192.168.4.112:5998/eureka/
使用portal: 访问 http://192.168.1.228:8070/, 管理员帐号:apollo/admin
[root@VM228 apollo]# ./demo.sh stop
==== stopping portal ====
Stopped [11196]
==== stopping service ====
Stopped [11050]
咱们暂时不启用它
参见:
https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97
(主要针对dubbo应用)
参考:https://github.com/ctripcorp/apollo/wiki/Java客户端使用指南
客户端部署跟咱们以前部署方式同样,不过部署以前,须要咱们对咱们的dubbo应用作一些调整:
apollo-client-项目分支-版本.jar(统一由架构部门或运维部门来发布)
以下:
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version> hy-linke-0.10.0</version>
</dependency>
在应用中配置好META-INF/app.properties, META-INF/app.properties 是可选的,并且
把原先配置(必须是properties格式)复制一下,而后经过Apollo提供的文本编辑模式所有粘帖到应用的application namespace,发布配置
若是原来是其它格式,如yml,请先转成properties格式
最好把原先的配置文件如bootstrap.properties, application.properties从项目中删除,固然,咱们也能够同时保留咱们原来的application.properties配置,可是这样可能会有冲突,若是在本地和配置中心有有同名的配置,那么使用配置中心, 不然就使用其中存在的一方, 若是两个地方都没有,那么就使用默认值, 若是默认值也没有,那么spring启动就可能会出现异常。
public class TestJavaConfigBean {
@Value("${timeout:100}")
private int timeout;
private int batch;
@Value("${batch:200}")
public void setBatch(int batch) {
this.batch = batch;
}
public int getTimeout() {
return timeout;
}
public int getBatch() {
return batch;
}
}
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public TestJavaConfigBean javaConfigBean() {
return new TestJavaConfigBean();
}
}
@ConfigurationProperties(prefix = "redis.cache")
public class SampleRedisConfig {
private int expireSeconds;
private int commandTimeout;
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
public void setCommandTimeout(int commandTimeout) {
this.commandTimeout = commandTimeout;
}
}
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public SampleRedisConfig redisConfigBean() {
return new SampleRedisConfig ();
}
}
,以下,@ApolloConfig 能够和@Value一块儿使用,ApolloConfigChangeListener能够监听配置变化:
public class TestApolloAnnotationBean {
@ApolloConfig
private Config config; //inject config for namespace application
@ApolloConfig("application")
private Config anotherConfig; //inject config for namespace application
@ApolloConfig("FX.apollo")
private Config yetAnotherConfig; //inject config for namespace FX.apollo
@Value("${batch:100}")
private int batch;
//config change listener for namespace application
@ApolloConfigChangeListener
private void someOnChange(ConfigChangeEvent changeEvent) {
//update injected value of batch if it is changed in Apollo
if (changeEvent.isChanged("batch")) {
batch = config.getIntProperty("batch", 100);
}
}
//config change listener for namespace application
@ApolloConfigChangeListener("application")
private void anotherOnChange(ConfigChangeEvent changeEvent) {
//do something
}
//config change listener for namespaces application and FX.apollo
@ApolloConfigChangeListener({"application", "FX.apollo"})
private void yetAnotherOnChange(ConfigChangeEvent changeEvent) {
//do something
}
//example of getting config from Apollo directly
//this will always return the latest value of timeout
public int getTimeout() {
return config.getIntProperty("timeout", 200);
}
//example of getting config from injected value
//the program needs to update the injected value when batch is changed in Apollo using @ApolloConfigChangeListener shown above
public int getBatch() {
return this.batch;
}
}
applicationKey= ${apolloValue}
获取默认namespace的配置(application)
Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
String someKey = "someKeyFromDefaultNamespace";
String someDefaultValue = "someDefaultValueForTheKey";
String value = config.getProperty(someKey, someDefaultValue);
使用:
@Autowired
TestJavaConfigBean javaConfigBean;
@Autowired
SampleRedisConfig redisConfig;
@Autowired
TestApolloAnnotationBean apolloAnnotationBean;
关于 META-INF/app.properties文件:它主要是用来定义app.id的。官方默认状况下,这个文件是不可缺乏的,可是为了简化你们的开发,我这边已经修改了源码,设置了默认值hy,因此,这个文件如今就变成不是必须配置的了
关于server.properties 文件,位于C:\opt\settings\server.properties或/opt/settings/server.properties ,它主要是用来定义env和idc参数的。官方默认状况下,这个文件是不可缺乏的,可是为了简化你们的开发,我这边已经修改了源码,设置了默认值env=dev,因此,这个文件如今就变成不是必须配置的了(若是有设置,那么,它是不可动态增长删除或修改, 只在启动的时候读取一次)
因此,如今来讲, 咱们已经不须要任何apollo配置文件了,咱们直接在portal上配置便可。
l jvm 参数
env idc
l 系统环境变量:
ENV, app.id, idc
l 配置文件
/META-INF/app.properties: app.id
server.properties: env, idc
位于:
/opt/data/{appId}/config-cache 或C:\opt\data\{appId}\config-cache
咱们的dubbo应用启动以前, apollo 必须先启动好,
不然,咱们dubbo应用会一直等待,直到apollo准备就绪,而且能够在控制台看到以下输出:
...
2018-03-01 18:01:59,932 [Apollo-RemoteConfigLongPollService-1] WARN com.ctrip.framework.apollo.internals.RemoteConfigLongPollService.doLongPollingRefresh:193 - Long polling failed, will retry in 16 seconds. appId: SampleApp, cluster: default, namespaces: application+FX.apollo, long polling url: null, reason: Get config services failed from http://192.168.1.228:8080/services/config?appId=SampleApp&ip=192.168.1.222 [Cause: Could not complete get operation [Cause: connect timed out]]
2018-03-01 18:02:19,932 [Apollo-RemoteConfigLongPollService-1] WARN com.ctrip.framework.apollo.internals.RemoteConfigLongPollService.doLongPollingRefresh:193 - Long polling failed, will retry in 32 seconds. appId: SampleApp, cluster: default, namespaces: application+FX.apollo, long polling url: null, reason: Get config services failed from http://192.168.1.228:8080/services/config?appId=SampleApp&ip=192.168.1.222 [Cause: Could not complete get operation [Cause: connect timed out]]
2018-03-01 18:02:55,933 [Apollo-RemoteConfigLongPollService-1] WARN com.ctrip.framework.apollo.internals.RemoteConfigLongPollService.doLongPollingRefresh:193 - Long polling failed, will retry in 64 seconds. appId: SampleApp, cluster: default, namespaces: application+FX.apollo, long polling url: null, reason: Get config services failed from http://192.168.1.228:8080/services/config?appId=SampleApp&ip=192.168.1.222 [Cause: Could not complete get operation [Cause: connect timed out]]
2018-03-01 18:04:03,934 [Apollo-RemoteConfigLongPollService-1] WARN com.ctrip.framework.apollo.internals.RemoteConfigLongPollService.doLongPollingRefresh:193 - Long polling failed, will retry in 120 seconds. appId: SampleApp, cluster: default, namespaces: application+FX.apollo, long polling url: null, reason: Get config services failed from http://192.168.1.228:8080/services/config?appId=SampleApp&ip=192.168.1.222 [Cause: Could not complete get operation [Cause: connect timed out]]
...
注意其中轮询时间是从1,2,3,4,8,14,32, 方式一直增加,单位是s
问题:
由于数据库是: http://192.168.4.112:5998/eureka/
2018-03-22 12:01:41.470 INFO 3840 --- [ost-startStop-1] c.c.f.a.biz.service.BizDBPropertySource : Load config from DB : eureka.service.url = http://192.168.4.112:5998/eureka/
而portal 的参数是:
-Dapollo_profile=github,auth -Ddev_meta=http://localhost:5998/
因而portal 就启动不了。。
2018-03-22 12:02:30.321 ERROR 8536 --- [HealthChecker-1] c.c.f.a.portal.component.PortalSettings : Env is down. env: DEV, failed times: 3, meta server address: http://localhost:5998/
2018-03-22 12:02:40.322 ERROR 8536 --- [HealthChecker-1] c.c.f.a.portal.component.PortalSettings : Env health check failed, maybe because of meta server down or configure wrong meta server address. env: DEV, meta server address: http://localhost:5998/
com.ctrip.framework.apollo.common.exception.ServiceException: No available admin server. Maybe because of meta server down or all admin server down. Meta server address: http://localhost:5998/
at com.ctrip.framework.apollo.portal.component.RetryableRestTemplate.getAdminServices(RetryableRestTemplate.java:172)
at com.ctrip.framework.apollo.portal.component.RetryableRestTemplate.execute(RetryableRestTemplate.java:90)
at com.ctrip.framework.apollo.portal.component.RetryableRestTemplate.get(RetryableRestTemplate.java:56)
at com.ctrip.framework.apollo.portal.api.AdminServiceAPI$HealthAPI.health(AdminServiceAPI.java:47)
at com.ctrip.framework.apollo.portal.component.PortalSettings$HealthCheckTask.isUp(PortalSettings.java:127)
at com.ctrip.framework.apollo.portal.component.PortalSettings$HealthCheckTask.run(PortalSettings.java:103)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
2018-03-22 12:02:40.328 ERROR 8536 --- [HealthChecker-1] c.c.f.a.portal.component.PortalSettings : Env is down. env: DEV, failed times: 4, meta server address: http://localhost:5998/
2018-03-22 12:02:50.530 INFO 8536 --- [HealthChecker-1] c.c.f.a.portal.component.PortalSettings : Env revived because env health check success. env: DEV
解决:
都改为localhost, 或者ip 就能够了Apollo配置中心