{% include toc %} Java Chassis作为一个微服务框架,支持多样化的部署模式。
这种方式直接部署在物理机或虚拟机操作系统上,Chassis微服务以Java进程的方式启动:
请保证网络在同一个局域网内,或能互通。
在微服务项目的pom.xml
中添加以下依赖:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <!--change to your main class--> <mainClass>${your-package}.Application</mainClass> </manifest> <manifestEntries> <Class-Path>. </Class-Path> </manifestEntries> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>target/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
之后运行:
mvn package
在target
目录下拷贝生成的微服务jar包和lib
(依赖jar)至任何目录,运行即可:
java -jar ${project.artifactId}-${project.version}.jar
提示:
- 如果需要更改
microservice.yaml
中的配置项又不希望重新打包,可以直接编写一个新的microservice.yaml
,然后放置于微服务jar包同级别目录,重启微服务即可;- 请修改上面打包依赖配置中
<mainClass>${your-package}.Application</mainClass>
为微服务启动MainClass。
这种方式适合部署测试环境,当微服务数据量比较多的情况下能够大幅减少部署的工作量,一键拉起所有的微服务:
我们使用io.fabric8的maven插件从打包,镜像在微服务项目的pom.xml
中添加以下依赖:
<build> <pluginManagement> <plugins> <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <images> <image> <name>${project.artifactId}:${project.version}</name> <alias>${project.artifactId}</alias> <build> <from>openjdk:8-jdk-stretch</from> <ports> <port>8080</port> </ports> <volumes> <volume>/docker</volume> </volumes> <assembly> <mode>dir</mode> <basedir>/</basedir> <descriptor>assembly.xml</descriptor> </assembly> <entryPoint> <shell>java $JAVA_OPTS -jar /docker/${project.artifactId}-${project.version}.jar</shell> </entryPoint> </build> </image> </images> </configuration> <executions> <execution> <id>build</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build> <profiles> <profile> <id>docker</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <!--change to your main class--> <mainClass>${your-package}.Application</mainClass> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>target/lib</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> </plugin> </plugins> </build> </profile> </profiles>
在项目源代码src\main
下,创建一个docker
目录,之后在此目录中创建一个assembly.xml
文件,填入下面的内容:
<?xml version="1.0" encoding="UTF-8"?> <assembly> <id>installer</id> <fileSets> <fileSet> <directory>${project.build.directory}/lib</directory> <outputDirectory>/docker/lib</outputDirectory> <fileMode>0644</fileMode> <directoryMode>0755</directoryMode> </fileSet> </fileSets> <files> <file> <source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source> <outputDirectory>/docker</outputDirectory> <destName>${project.artifactId}-${project.version}.jar</destName> </file> </files> </assembly>
完成之后的项目效果:
运行:
mvn package -Pdocker
等待打包完成,会有提示镜像生成成功并注册到本地镜像库的提示。
提示:
- 请修改上面打包依赖配置中
<mainClass>${your-package}.Application</mainClass>
为微服务启动MainClass;- 为了保留普通打包方式,docker打包方式配置为maven profile,即``-Pdocker`;
- 如果是使用windows系统,请安装docker machine,并且确保docker machine vm启动中;
- 打包的镜像会默认安装在本地镜像库中,如果需要上传外部镜像库例如中央库,可以使用下面的命令:
mvn -Ddocker.registry=registry.hub.docker.com/${username} -Ddocker.username=${username} -Ddocker.password=${password} docker:push
将所有的微服务打包为镜像后,就可以使用Docker Compose组织它们,我们给一个例子:
version: '2.0' services: service-center: image: "servicecomb/service-center" hostname: service-center ports: - "30100:30100" mysql-write-db: image: "mysql:latest" hostname: write_db_server environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=seckill - MYSQL_USER=seckill - MYSQL_PASSWORD=password ports: - "3306" activemq: image: "webcenter/activemq:latest" hostname: queue-server ports: - "61616" admin-service: image: "seckill-admin-service:0.2.0-SNAPSHOT" hostname: admin-service links: - "mysql-write-db:write_db.servicecomb.io" environment: - JAVA_OPTS=-Dspring.profiles.active=prd,cse -Dendpoints.shutdown.enabled=true ports: - "8081:8081"
为了能够使containers互联互通,使用links
指定链接关系,ports
用于映射到Docker Host的端口,关于Docker Compose Yaml配置的更多信息,可以参见这篇文档。
编写好docker-compose.yml后,切换到此文件目录,执行:
docker-compose up
即可将所有的微服务都拉起来。
提示:
- docker-compose默认寻找当前文件夹下的docker-compose.yml文件作为编排配置文件,如果需要指定文件名或路径,请使用
docker-compose -f ${fullFileName}
;- 如果container无需对外发布端口则可以不设置
ports
。
Kubernetes是谷歌开源的容器集群管理系统,目前已经具备生产化成熟度,虽然Java Chassis作为一个微服务框架与Kubernetes处于不同层次,但由于Kubernetes同样拥有注册-发现、弹性伸缩、监控等方面的功能,因此很容易与Java Chassis中相关功能搞混,我们需要比较深入的理解两者的差异。
上图中,我们省去了网络细节,关注这几个点:
NodePort
,ClusterIP
和LoadBalancer
,后两种具有负载均衡能力,LoadBalancer
需要PaaS平台实现,因此对于本地Kubernetes集群多用ClusterIP
;上图是Java Chassis基本原理,我们同样解释几个点:
综合上述,我们总结为下面的表格:
说明项 | Kubernetes | Java Chassis |
---|---|---|
定位 | 容器集群管理系统 | 微服务框架 |
层次 | PaaS | SDK |
Service的含义 | 逻辑概念,用selector指向containers | 业务概念,微服务拆分后的业务 |
注册和发现 | NameService为中心 | ServiceCenter为中心 |
弹性伸缩 | 调度资源启动或停止实例 | 无此能力 |
负载均衡 | name + selector机制 | Consumer端动态发现实例的变化 |
监控 | 有集成的监控系统 | 只作为监控系统的数据源 |
理解了上面的内容之后,我们可以如下设计 Java Chassis在Kubernetes集群中的部署:
servicecomb.service.publishAddress
指定发布地址;提示:
- 请牢记 Java Chassis的负载均衡机制与Kubernetes的负载均衡机制无关,即Java Chassis的负载均衡并不走name + selector机制,也不需要配置Service;
- 上述部署细节可依据实际环境(例如网络)自行调整。
Company是我们提供的一个有趣味性的演示项目:
如何在Kubernetes集群中部署Company:http://servicecomb.apache.org/cn/docs/company-on-kubernetes/