由于项目需求,需要在单台服务器上部署apollo,并配置多环境,试了官网的快速开始docker,用里面的sh文件启动,实现多环境较为麻烦(需要该配置文件和脚本文件),后来在网上
源码地址:
https://github.com/ctripcorp/apollo/tree/v1.2.0
创建数据库
apollo 要部署三个模块:apollo-configservice,apollo-adminservice,apollo-portal
其中apollo-configservice,apollo-adminservice要分环境部署,各个环境下apollo-configservice,apollo-adminservice公用一个数据库(参考官网),apollo-portal独用一个数据库
共五个个数据库,apollo-configservice,apollo-adminservice分别在dev,fat,uat,pro一个数据库,apollo-portal一个数据库,如下图所示:
数据库修改ServerConfig表中的记录:
下面每一个表的eureka.service.url都做对应修改
ApolloConfigDB_DEV
http://192.168.64.201:8080/eureka/
ApolloConfigDB_FAT
http://192.168.64.201:8081/eureka/
ApolloConfigDB_UAT
http://192.168.64.201:8082/eureka/
ApolloConfigDB_PRO
http://192.168.64.201:8083/eureka/
ApolloPortalDB
apollo-portal 的修改有所不同,同样是ServerConfig表,但是不是配置URL而是配置启用的环境,如下
dev,fat,uat,pro
官网下载对应的版本的源码,导入idea,如下图,我这里标记了几个重要的模块以及目录
直接使用maven打包(不用apollo自带的build.sh,这种方式要改配置),直接打包后,取到config、admin、portal对应的zip包以及对应的Dockerfile文件,以及创建.env文件、docker-compose.yml、apollo-env.properties文件,最终文件目录结构如下:
.env文件
该文件用于定义docker-compose.yml文件中使用的变量,主要是暴露的端口定义,数据库连接串信息
VERSION=1.2.0
LOG_BASE_DIR=/data/apollo
BUILD_BASE_DIR=/data/docker-image
IP_ADDRESS=192.168.64.201
CONFIG_PORT_DEV=8080
CONFIG_PORT_FAT=8081
CONFIG_PORT_UAT=8082
CONFIG_PORT_PRO=8083
ADMIN_PORT_DEV=8090
ADMIN_PORT_FAT=8091
ADMIN_PORT_UAT=8092
ADMIN_PORT_PRO=8093
DATASOURCE_URL_DEV=jdbc:mysql://192.168.64.201:13306/huayun_ApolloConfigDB_DEV?characterEncoding=utf8
DATASOURCE_URL_FAT=jdbc:mysql://192.168.64.201:13306/huayun_ApolloConfigDB_FAT?characterEncoding=utf8
DATASOURCE_URL_UAT=jdbc:mysql://192.168.64.201:13306/huayun_ApolloConfigDB_UAT?characterEncoding=utf8
DATASOURCE_URL_PRO=jdbc:mysql://192.168.64.201:13306/huayun_ApolloConfigDB_PRO?characterEncoding=utf8
PORTAL_DATASOURCE_URL=jdbc:mysql://192.168.64.201:13306/huayun_ApolloPortalDB?characterEncoding=utf8
DATASOURCE_USERNAME=root
DATASOURCE_PASSWORD=root
apollo-env.properties
dev.meta=http://192.168.64.201:8080
fat.meta=http://192.168.64.201:8081
uat.meta=http://192.168.64.201:8082
pro.meta=http://192.168.64.201:8083
docker-compose.yml
version: '3'
services:
# 开发环境 configservice
apollo-configservice-dev:
container_name: apollo-configservice-dev
build: apollo-configservice/
image: apollo-configservice
restart: always
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_DEV}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${CONFIG_PORT_DEV}
volumes:
- ${LOG_BASE_DIR}/apollo-configservice-dev/logs:/opt/logs
ports:
- "${CONFIG_PORT_DEV}:8080"
# 开发环境 adminservice
apollo-adminservice-dev:
container_name: apollo-adminservice-dev
build: apollo-adminservice/
image: apollo-adminservice
restart: always
depends_on:
- apollo-configservice-dev
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_DEV}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${ADMIN_PORT_DEV}
volumes:
- ${LOG_BASE_DIR}/apollo-adminservice-dev/logs:/opt/logs
ports:
- "${ADMIN_PORT_DEV}:8090"
# fat configservice
apollo-configservice-fat:
container_name: apollo-configservice-fat
build: apollo-configservice/
image: apollo-configservice
restart: always
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_FAT}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${CONFIG_PORT_FAT}
volumes:
- ${LOG_BASE_DIR}/apollo-configservice-fat/logs:/opt/logs
ports:
- "${CONFIG_PORT_FAT}:8080"
# fat adminservice
apollo-adminservice-fat:
container_name: apollo-adminservice-fat
build: apollo-adminservice/
image: apollo-adminservice
restart: always
depends_on:
- apollo-configservice-fat
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_FAT}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${ADMIN_PORT_FAT}
volumes:
- ${LOG_BASE_DIR}/apollo-adminservice-fat/logs:/opt/logs
ports:
- "${ADMIN_PORT_FAT}:8090"
# uat configservice
apollo-configservice-uat:
container_name: apollo-configservice-uat
build: apollo-configservice/
image: apollo-configservice
restart: always
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_UAT}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${CONFIG_PORT_UAT}
volumes:
- ${LOG_BASE_DIR}/apollo-configservice-uat/logs:/opt/logs
ports:
- "${CONFIG_PORT_UAT}:8080"
# uat adminservice
apollo-adminservice-uat:
container_name: apollo-adminservice-uat
build: apollo-adminservice/
image: apollo-adminservice
restart: always
depends_on:
- apollo-configservice-uat
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_UAT}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${ADMIN_PORT_UAT}
volumes:
- ${LOG_BASE_DIR}/apollo-adminservice-uat/logs:/opt/logs
ports:
- "${ADMIN_PORT_UAT}:8090"
# pro configservice
apollo-configservice-pro:
container_name: apollo-configservice-pro
build: apollo-configservice/
image: apollo-configservice
restart: always
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PRO}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${CONFIG_PORT_PRO}
volumes:
- ${LOG_BASE_DIR}/apollo-configservice-pro/logs:/opt/logs
ports:
- "${CONFIG_PORT_PRO}:8080"
# pro adminservice
apollo-adminservice-pro:
container_name: apollo-adminservice-pro
build: apollo-adminservice/
image: apollo-adminservice
restart: always
depends_on:
- apollo-configservice-pro
environment:
SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PRO}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
EUREKA_INSTANCE_IP_ADDRESS: ${IP_ADDRESS}
EUREKA_INSTANCE_HOME_PAGE_URL: http://${IP_ADDRESS}:${ADMIN_PORT_PRO}
volumes:
- ${LOG_BASE_DIR}/apollo-adminservice-pro/logs:/opt/logs
ports:
- "${ADMIN_PORT_PRO}:8090"
# portal
apollo-portal:
container_name: apollo-portal
build: apollo-portal/
image: apollo-portal
restart: always
depends_on:
- apollo-adminservice-dev
- apollo-adminservice-fat
- apollo-adminservice-uat
- apollo-adminservice-pro
environment:
SPRING_DATASOURCE_URL: ${PORTAL_DATASOURCE_URL}
SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
APOLLO_PROFILE: github,auth
volumes:
- ${LOG_BASE_DIR}/apollo-portal/logs:/opt/logs
- ${BUILD_BASE_DIR}/docker-compose-huayun/apollo-env.properties:/apollo-portal/config/apollo-env.properties
ports:
- "8070:8070"
各个环境下的apollo-configservice和apollo-adminservice中有两个参数解释一下:
EUREKA_INSTANCE_IP_ADDRESS 指定服务想eureaka注册时使用物理机器IP地址
EUREKA_INSTANCE_HOME_PAGE_URL 该参数配置当前服务的注册全路径,如果不配置,Java应用客户端无法连接apollo服务端
将修改后的docker-compose文件夹打包,上传到centos主机的/data/docker-image目录下(你可以更改,记得更改.env中的配置的BUILD_BASE_DIR对应的值为你的目录即可),解压,如下:
进入docker-compose目录
启动容器
docker-compose up -d
观察各个服务启动的日志(我这里的日志挂在在了物理机的/data/apollo目录下),服务一开始会有报错,因为注册中心启动需要一定的时间
确认服务启动
查看日志,看到portal有如下日志,则服务都已启动
或查看注册中心注册的服务信息,地址分别是:
http://192.168.64.201:8080/
http://192.168.64.201:8081/
http://192.168.64.201:8082/
http://192.168.64.201:8083/
看到服务注册成功即可。
访问apollo后台
http://192.168.64.201:8070/
登录用户名密码:apollo/admin
登录后验证创建用户,看是不是会报错,能创建用户成功就OK了。
新建一个springboot2的web项目,整合apollo客户端,项目结构如下:
pom.xml,加入apollo客户端依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.6.RELEASEversion>
<relativePath/>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>com.huayungroupId>
<artifactId>huayun-apollo-testartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.8version>
dependency>
<dependency>
<artifactId>apollo-clientartifactId>
<groupId>com.ctrip.framework.apollogroupId>
<version>1.5.0version>
dependency>
dependencies>
project>
启动类App.java,加@EnableApolloConfig开启apollo
package com.huayun.apollo;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableApolloConfig
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
application.yml定义服务端口
server:
port: 8001
apollo-env.properties定义apollo服务的meta信息
dev.meta=http://192.168.64.201:8080
fat.meta=http://192.168.64.201:8081
uat.meta=http://192.168.64.201:8082
pro.meta=http://192.168.64.201:8083
app.properties定义appid,与apollo服务端appId对应
app.id=huayun-apollo-test
测试controller ApolloController.java,就是简单的获取apollo中配置的aaa的值,并返回
package com.huayun.apollo.controller;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ApolloController {
@GetMapping("/test")
public Object test(){
Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
String someKey = "aaa";
int someDefaultValue = -1;
int value = config.getIntProperty(someKey, someDefaultValue);
return value;
}
}
apollo服务端配置aaa在各个环境不同的值
为测试项目配置App的启动参数 -Denv=dev
分别为env配置不同的环境,测试获取到的aaa的值,aaa的值为对应的环境的值,那么就成功了。