上文介绍了 SOFARPC 的简单使用。在生产环境中,一般会将 SOFARPC 整合到 SpringBoot 中。蚂蚁金服提供了 SOFABoot 框架,SOFABoot 是蚂蚁金服开源的基于 Spring Boot 的研发框架,它在 Spring Boot 的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等等能力。php
在加强了 Spring Boot 的同时,SOFABoot 提供了让用户能够在 Spring Boot 中很是方便地使用 SOFA 中间件的能力。当前 SOFABoot 的 2.3.1 版本是基于 Spring Boot 1.4.2.RELEASE 来构建的。java
蚂蚁金服SOFA-Boot整合SOFA-RPC(上篇) github
蚂蚁金服SOFA-Boot整合SOFA-RPC(下篇) spring
SOFABoot 在 Spring Boot 的基础上,提供了如下能力:docker
在 Spring Boot 健康检查能力的基础上,提供了 Readiness Check 的能力,保证应用实例安全上线。apache
中间件框架自动发现应用的日志实现依赖并独立打印日志,避免中间件和应用日志实现绑定,经过 sofa-common-tools 实现。编程
基于 SOFAArk 框架提供类隔离能力,方便使用者解决各类类冲突问题。json
统一管控、提供中间件统一易用的编程接口、每个 SOFA 中间件都是独立可插拔的组件。
SOFABoot 基于 Spring Boot 的基础上进行构建,而且彻底兼容 Spring Boot。
要使用 SOFABoot,须要先准备好基础环境,SOFABoot 依赖如下环境:
SOFABoot 是直接构建在 Spring Boot 之上,所以能够使用 Spring Boot 的工程生成工具来生成。添加一个 Web 的依赖,以便最后在浏览器中查看效果。
在建立好一个 Spring Boot 的工程以后,接下来就须要引入 SOFABoot 的依赖。首先,须要将上文中生成的 Spring Boot 工程的 zip 包解压后,修改 maven 项目的配置文件 pom.xml。
替换 spring-boot-starter-parent 为相应版本的 sofaboot-dependencies,例如:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
复制代码
替换为:
<parent>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofaboot-dependencies</artifactId>
<version>2.3.1</version>
</parent>
复制代码
添加 SOFABoot 健康检查扩展能力的依赖:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>healthcheck-sofa-boot-starter</artifactId>
</dependency>
复制代码
最后,在工程的 application.properties 文件下添加一个 SOFABoot 必需要使用的参数。
# Application Name
spring.application.name=SOFABoot Example
# logging path
logging.path=./logs
复制代码
运行 main() 方法,项目启动之后,控制台的日志输出以下:
2018-05-09 09:56:48.305 INFO 15097 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-05-09 09:56:48.309 INFO 15097 --- [ main] c.o.s.r.e.SofaBootExampleApplication : Started SofaBootExampleApplication in 2.551 seconds (JVM running for 3.046)
2018-05-09 09:57:46.005 INFO 15097 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-05-09 09:57:46.005 INFO 15097 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-05-09 09:57:46.021 INFO 15097 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
复制代码
[
{
"GroupId": "com.alipay.sofa",
"Doc-Url": "https://github.com/alipay/sofa-boot",
"ArtifactId": "infra-sofa-boot-starter",
"Bulit-Time": "2018-04-18T22:19:09+0800",
"Commit-Time": "2018-04-18T22:07:52+0800",
"Commit-Id": "466f0e039b250ff7b201dc693eec7fa07eb21ad7",
"Version": "2.3.1"
}
]
复制代码
{
"status": "UP",
"sofaBootComponentHealthCheckInfo": {
"status": "UP"
},
"springContextHealthCheckInfo": {
"status": "UP"
},
"DiskSpaceHealthIndicator": {
"status": "UP",
"total": 250790436864,
"free": 208612020224,
"threshold": 10485760
}
}
复制代码
status: "UP"
表示应用 Readiness Check
的就绪状态是健康的。
{
"status": "UP",
"sofaBootComponentHealthCheckInfo": {
"status": "UP",
"Middleware": {
}
},
"springContextHealthCheckInfo": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"total": 250790436864,
"free": 208612528128,
"threshold": 10485760
}
}
复制代码
在上面的 application.properties 里面,咱们配置的日志打印目录是 ./logs 即当前应用的根目录(咱们能够根据本身的实践须要配置),在当前工程的根目录下能够看到相似以下结构的日志文件:
./logs
├── health-check
│ ├── sofaboot-common-default.log
│ └── sofaboot-common-error.log
├── infra
│ ├── common-default.log
│ └── common-error.log
└── spring.log
复制代码
若是应用启动失败或者健康检查返回失败,能够经过相应的日志文件找到错误的缘由,有些须要关注 common-error.log 日志。
SOFABoot 使用一系列后缀为 -sofa-boot-starter 来标示一个中间件服务,若是想要使用某个中间件,直接添加对应的依赖便可。进一步引入 SOFA-RPC 的 starter 依赖:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
复制代码
选择 Zookeeper 做为服务注册列表,在 pom.xml 文件中引入相关依赖:
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
<version>0.10</version>
</dependency>
复制代码
注意将 zkclient 重复的依赖排除在外,以避免引发冲突。
在 application.properties 中进一步配置 zookeeper 的地址信息。
# zookeeper address list
com.alipay.sofa.rpc.registry.address=zookeeper://127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183?file=/home/admin/registry
复制代码
为了方便起见,本地使用 docker 环境对 zookeeper 集群进行容器编排。多个 zookeeper 节点经过逗号分隔,file 参数指定当 zookeeper 不可用时,能够利用本地缓存文件进行服务发现。
编写 docker-compose.yml 文件以下:
version: '2'
services:
zoo1:
image: zookeeper:latest
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo2:
image: zookeeper:latest
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888
zoo3:
image: zookeeper:latest
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888
复制代码
进入 docker-compose.yml 所在文件目录, 运行 docker-compose up -d
启动3台 zookeeper 容器。启动完成后,运行 docker-compose ps
查看进程状态以下:
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------
zookeeper_zoo1_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2181->2181/tcp, 2888/tcp, 3888/tcp
zookeeper_zoo2_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2182->2181/tcp, 2888/tcp, 3888/tcp
zookeeper_zoo3_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2183->2181/tcp, 2888/tcp, 3888/tcp
复制代码
zookeeper 容器集群启动完成,若是想要查看集群 leader,能够运行 docker exec -it [container-id] /bin/bash
进入容器运行 zkServer.sh status
逐一查看。这里加以不累述!
在要使用的 XML 配置文件中将头部 xsd 文件的声明设置为以下,这样就可以使用 SOFABoot 定义的 XML 元素进行开发。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sofa="http://sofastack.io/schema/sofaboot" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd" default-autowire="byName">
复制代码
HelloSyncService.java
public interface HelloSyncService {
String saySync(String string);
}
复制代码
HelloSyncServiceImpl.java
public class HelloSyncServiceImpl implements HelloSyncService {
@Override
public String saySync(String sync) {
return sync;
}
}
复制代码
simple-server-example.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sofa="http://sofastack.io/schema/sofaboot" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd" default-autowire="byName">
<bean id="helloSyncServiceImpl" class="com.ostenant.sofa.rpc.example.simple.HelloSyncServiceImpl"/>
<!-- 以多种通讯协议发布服务 -->
<sofa:service ref="helloSyncServiceImpl" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.bolt/>
<sofa:binding.rest/>
<sofa:binding.dubbo/>
</sofa:service>
</beans>
复制代码
经过 sofa:service
元素将该服务发布,其中 ref
属性表示发布的服务实例,interface 属性表示该服务的接口。
SimpleServerApplication.java
@ImportResource({ "classpath:simple-server-example.xml" })
@SpringBootApplication
public class SimpleServerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SimpleServerApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
}
}
复制代码
simple-client-example.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sofa="http://sofastack.io/schema/sofaboot" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd" default-autowire="byName">
<!-- bolt引用 -->
<sofa:reference id="boltHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.bolt/>
</sofa:reference>
<!-- rest引用 -->
<sofa:reference id="restHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.rest/>
</sofa:reference>
<!-- dubbo引用 -->
<sofa:reference id="dubboHelloSyncServiceReference" interface="com.ostenant.sofa.rpc.example.simple.HelloSyncService">
<sofa:binding.dubbo/>
</sofa:reference>
</beans>
复制代码
SimpleClientApplication.java
@ImportResource({ "classpath:simple-client-example.xml" })
@SpringBootApplication
public class SimpleClientApplication {
public static void main(String[] args) {
System.setProperty("server.port", "8081");
SpringApplication springApplication = new SpringApplication(SimpleClientApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
HelloSyncService boltHelloSyncService = (HelloSyncService) applicationContext.getBean("boltHelloSyncServiceReference");
HelloSyncService restHelloSyncService = (HelloSyncService) applicationContext.getBean("restHelloSyncServiceReference");
HelloSyncService dubboHelloSyncService = (HelloSyncService) applicationContext.getBean("dubboHelloSyncServiceReference");
System.out.println("Bolt result:" + boltHelloSyncService.saySync("bolt"));
System.out.println("Rest result:" + restHelloSyncService.saySync("rest"));
System.out.println("Dubbo result:" + dubboHelloSyncService.saySync("dubbo"));
}
}
复制代码
客户端控制台输出日志以下:
Bolt result: bolt
Rest result: rest
Dubbo result: dubbo
复制代码
对于同一个服务,在服务发布方配置时,可在以 sofa:service
中经过 sofa:binding.xxx
提供多种协议通道配置;在服务消费方配置时,能够在 sofa:reference
中经过 sofa:binding.xxx
提供对不一样通道服务的引用。
本文引入了 SOFA-Boot 框架,对 SOFA-Boot 的将康检查功能和日志管理的使用进行了简单说明,而后在 SOFA-Boot 环境中引入了 SOFA-RPC 框架,并提供了一个完整的服务发布和注册的示例程序。
关于 SOFA-RPC 更丰富、强大的功能介绍,下篇敬请期待!
欢迎关注技术公众号: 零壹技术栈
本账号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。