SOFA Stack
sofa-registry
sofa-rpc
JDK 1.8
Maven 3
sofa-boot 3.6.0
sofa-registry 5.4.2
sofa-rpc 5.7.7
选择在Linux上单机快速部署,其他部署方式参考文档:SOFA Registry服务端部署。
mkdir -p /opt/sofa-registry
cd /opt/sofa-registry
wget https://github.com/sofastack/sofa-registry/releases/download/v5.4.2/registry-integration-fix.tgz
tar -zvxf registry-integration-fix.tgz
cd bin
./startup.sh
可访问三个角色提供的健康监测 API,或查看日志 logs/registry-startup.log,以检查是否启动成功:
# 查看meta角色的健康检测接口:
$ curl http://localhost:9615/health/check
{"success":true,"message":"... raftStatus:Leader"}
# 查看data角色的健康检测接口:
$ curl http://localhost:9622/health/check
{"success":true,"message":"... status:WORKING"}
# 查看session角色的健康检测接口:
$ curl http://localhost:9603/health/check
{"success":true,"message":"..."}
这里特别注意查看一下logs/registry-integration-std.out
日志中末尾的这几行:
...
[2021-02-25 17:52:40,981][INFO][main][SessionServerBootstrap] - Session server Environment: DataCenter DefaultDataCenter,Region DEFAULT_ZONE,ProcessId 0aca3f241614246760981100119050
[2021-02-25 17:52:40,983][INFO][main][SessionServerBootstrap] - Raft Client started! Leader:192.168.11.11:9614
[2021-02-25 17:52:41,071][INFO][main][SessionServerBootstrap] - Register MetaServer Session Node success!get data node list {DefaultDataCenter={192.168.11.11=DataNode{ip=192.168.11.11}}}
[2021-02-25 17:52:41,078][INFO][main][SessionServerBootstrap] - Get all dataCenter from meta Server success!
[2021-02-25 17:52:41,091][INFO][main][SessionServerBootstrap] - MetaServer connected meta server! Port:9610
[2021-02-25 17:52:41,095][INFO][main][SessionServerBootstrap] - Session Scheduler started!
[2021-02-25 17:52:41,286][INFO][main][SessionServerBootstrap] - Open http server port 9603 success!
[2021-02-25 17:52:41,303][INFO][main][SessionServerBootstrap] - Session server started! port:9600
[2021-02-25 17:52:41,447][INFO][main][SessionServerBootstrap] - Initialized Session Server...
[2021-02-25 17:52:41,458][INFO][main][SessionServerInitializer] - Started SessionServer
[2021-02-25 17:52:41,508][INFO][main][RegistryApplication] - localhost:9603 health check success.
其中有几个IP:
[2021-02-25 17:52:40,983][INFO][main][SessionServerBootstrap] - Raft Client started! Leader:192.168.11.11:9614
[2021-02-25 17:52:41,071][INFO][main][SessionServerBootstrap] - Register MetaServer Session Node success!get data node list {DefaultDataCenter={192.168.11.11=DataNode{ip=192.168.11.11}}}
一定要注意这几个IP是否是自己想要绑定的IP,如果不是,或者几个IP不一致,可能是有多个网卡导致的。如果不做任何处理,可能会导致sofa-rpc服务注册失败、调用失败等等,解决方法可参考:sofastack/sofa-registry/issues/35
ifconfig
查看网卡列表,找到自己需要绑定的网卡名称,比如eth0
.bin/startup.sh
,在JVM参数中添加-Dnetwork_interface_binding=eth0
:# set user.home
JAVA_OPTS="$JAVA_OPTS -Duser.home=${BASE_DIR}"
# 添加下面的参数可绑定网卡
# set network
JAVA_OPTS="$JAVA_OPTS -Dnetwork_interface_binding=eth0"
# springboot conf
SPRINGBOOT_OPTS="${SPRINGBOOT_OPTS} --logging.config=${BASE_DIR}/conf/logback-spring.xml"
sh shutdown.sh
sh startup.sh
新建父项目sofa-registry-demo
,创建三个子项目:
sofa-api
:API定义,用于生产者发布服务和消费者订阅服务。sofa-provider
:提供服务。sofa-consumer
:消费服务并提供对外访问入口。设置sofa-registry-demo
的父项目为sofaboot-dependencies
,这样所有子项目可非常方便饮用sofa依赖:
<parent>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofaboot-dependencies</artifactId>
<version>3.6.0</version>
</parent>
sofa-registry-demo
的pom文件中管理sofa-api
版本:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.szkingdom.sofa</groupId>
<artifactId>sofa-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
在sofa-api
子项目中定义接口:
public interface CalculatorService {
/**
* add
* @param a a
* @param b b
* @return a+b
*/
int add(int a, int b);
/**
* sub
* @param a a
* @param b b
* @return a - b
*/
int sub(int a, int b);
/**
* multiply
* @param a a
* @param b b
* @return a*b
*/
int multiply(int a, int b);
/**
* divide
* @param a a
* @param b b
* @return a/b
*/
int divide(int a, int b);
}
在sofa-provider
子项目中引入依赖:
<!-- rpc starter用于rpc服务暴露 -->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
<!-- sofa api用于服务实现 -->
<dependency>
<groupId>com.szkingdom.sofa</groupId>
<artifactId>sofa-api</artifactId>
</dependency>
<!-- registry client用于注册中心服务注册 -->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>registry-client-all</artifactId>
</dependency>
<!-- logback classic用于日志打印 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
实现sofa-api
中定义的接口:
@SofaService(interfaceType = CalculatorService.class, bindings = {@SofaServiceBinding(bindingType = "bolt")})
@Service
public class CalculatorServiceImpl implements CalculatorService {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int sub(int a, int b) {
return a - b;
}
@Override
public int multiply(int a, int b) {
return a * b;
}
@Override
public int divide(int a, int b) {
return a / b;
}
}
注意需要使用@Service
和@SofaService
双重注解,即需注册成spring bean,否则sofa-rpc
无法扫描到服务,也不会注册到注册中心。
bindings
属性可以指定服务暴露的协议,可以指定一种协议,也可以指定多种协议,这里选择阿里的bolt
协议,更多协议请参考:SOFARPC
创建启动类:
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
新增application.properties配置文件:
spring.application.name=SOFA-PROVIDER
com.alipay.sofa.rpc.registry.address=sofa://192.168.11.11:9603
运行启动类启动项目,可访问sofa-registry api 查看注册的服务列表:
curl localhost:9622/digest/datum/count
# publisher数量变为1
CacheDigest [Datum] size of datum in DefaultDataCenter is 1,[Publisher] size of publisher in DefaultDataCenter is 1
curl localhost:9603/digest/getDataInfoIdList
# 可以查看所有发布的服务
["github.clyoudu.sofa.api.CalculatorService:1.0@DEFAULT#@#DEFAULT_INSTANCE_ID#@#SOFA"]
如果访问registry接口未找到注册的服务,可以到sofa-provider
启动的机器上的~/logs/registry/common-err.log
查看error日志,如果发现是访问的registry ip地址不对,比如并不是期望绑定的IP,可以放回上文看看是否是存在多个网卡但未设置network_interface_binding
导致的。
在sofa-consumer
子项目中引入依赖:
<!-- rpc starter用于rpc服务订阅 -->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
<!-- sofa api用于服务引用 -->
<dependency>
<groupId>com.szkingdom.sofa</groupId>
<artifactId>sofa-api</artifactId>
</dependency>
<!-- registry client用于注册中心服务注册 -->
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>registry-client-all</artifactId>
</dependency>
<!-- 用于暴露http接口用于外部调试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
使用sofa-api
中定义的接口并暴露http接口:
@RestController
@RequestMapping("test")
public class TestController {
@SofaReference(interfaceType = CalculatorService.class, binding = @SofaReferenceBinding(bindingType = "bolt"))
private CalculatorService calculatorService;
@GetMapping("cal")
public Integer result(@RequestParam Integer a, @RequestParam Integer b, @RequestParam Integer c,
@RequestParam Integer d, @RequestParam Integer e) {
// (a+b-c)*d/e
return calculatorService
.divide(calculatorService.multiply(calculatorService.sub(calculatorService.add(a, b), c), d), e);
}
}
@SofaReference
注解中的binding
属性必须在provider的bindings
列表中,否则会导致服务访问失败。
创建启动类:
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
新增application.properties配置文件:
spring.application.name=SOFA-CONSUMER
com.alipay.sofa.rpc.registry.address=sofa://10.202.63.36:9603
启动启动类,访问接口:http://localhost:8080/test/cal?a=1&b=2&c=1&d=10&e=5
,结果返回4,调用成功。