j-rpc
j-rpc 基于thrift 的 json 格式 rpc调用框架
目录结构
- j-rpc-base # 基础包
- j-rpc-server # server 包,主要包含:服务注册,方法接口,内置方法
- j-rpc-client # client 包
- j-rpc-registry # 注册与发现
- j-rpc-common #
- j-rpc-common-crud # j-jdbc 接口工具包
- j-rpc-common-trace # 调用链追踪
- j-rpc-starter # springboot starter
- j-rpc-test # 测试相关
- j-rpc-test-client # 客户端测试
- j-rpc-test-server # 服务端测试
- j-rpc-test-forward # 转发测试
- j-rpc-test-jmeter # jmeter 接口测试包
- j-rpc-apidoc # 根据线上服务方法生成的接口文档
简介
server 启动后,将连接信息注册到 zookeeper,client 监听 zk 服务节点树,将所有服务信息缓存到内存中。当发起一次调用请求时根据服务名,版本号,服务实例名等路由信息来获取一个连接信息,然后根据连接信息创建一个连接池(如果该连接池已存在,复用),从连接池取出一个将数据发送到 server。
基本用法
server:
参见 j-rpc-test-server
1. 引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-server</artifactId>
<version>${jrpc-version}</version>
</dependency>
2. 添加 spring 配置信息
j-rpc:
registry:
model: zookeeper # 目前仅支持 zookeeper
inet: 127.0.0.1 # 本机ip, 获取本机ip优先级 inet>inet-env>InetAddress.getLocalHost().getHostAddress()>127.0.0.1
inet-env: LOCAL_IP # 本级ip环境变量key
zookeeper:
address: 127.0.0.1:2181 # zk 地址 ,优先级 address>address-env>127.0.0.1:2181
address-env : ZK_ADDR # zk 地址环境变量
namespace: /com.github.jingshouyan.jrpc # 服务注册的namespace
session-timeout: 20000 #
connection-timeout: 5000 #
retry-interval-ms: 5000 #
server:
version: v2.0 #服务版本号 default:v1.0
port: 8999 #端口号 default:8888
name: test #服务名 default:j-rpc
timeout: 5000 # 接口超时时间 default:5000
maxReadBufferBytes: 102400 # 缓冲区最大长度 default:25 * 1024 * 1024 (25MB)
3. 实现 Method<T,R> 接口 或 AsyncMethod<T,R> 接口
@Data
public class IdQuery {
//基于 validation 的注解,如果验证不通过会返回 Code.PARAM_INVALID 错误码,如果想返回自定义的错误码,message 设置如下
@NotNull(message = BaseConstant.INVALID_CODE_PREFIX + TestCode.NAME_IS_NULL)
@Size(min = 4,max = 20)
private String name;
@Min(5)@Max(99)
private int age = 10;
@NotNull@Size(min = 1,max= 100)
private List<String> ids;
}
@Component("getUserInfo")
public class GetUserInfo implements Method<IdQuery,List<UserBean>> {
// 本方法只会在 idQuery 校验成功执行
@Override
public List<UserBean> action(Token token,IdQuery idQuery) {
// throw new JException(TestCode.JUST_ERROR); //通过异常返回错误码
// throw new JException(TestCode.JUST_ERROR,idQuery); //通过异常返回错误码,并返回一些数据
return idQuery.getIds().stream().map(id -> {
UserBean userBean = new UserBean();
userBean.setId(id);
userBean.setAge(idQuery.getAge());
userBean.setName(idQuery.getName());
return userBean;
}).collect(Collectors.toList());
}
}
@Component("getUserInfo2")
public class GetUserInfo2 implements AsyncMethod<IdQuery,List<UserBean>> {
// 本方法只会在 idQuery 校验成功执行
@Override
public Mono<List<UserBean>> action(Token token,IdQuery idQuery) {
// throw new JException(TestCode.JUST_ERROR); //通过异常返回错误码
// throw new JException(TestCode.JUST_ERROR,idQuery); //通过异常返回错误码,并返回一些数据
return Mono.fromCallable(() -> {
throw new JException(TestCode.JUST_ERROR,idQuery);//任何位置都可以使用来返回
return idQuery.getIds().stream().map(id -> {
UserBean userBean = new UserBean();
userBean.setId(id);
userBean.setAge(idQuery.getAge());
userBean.setName(idQuery.getName());
return userBean;
}).collect(Collectors.toList());
});
}
}
client:
参见 j-rpc-test-client
1. 引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-client</artifactId>
<version>${jrpc-version}</version>
</dependency>
2. 添加 spring 配置信息
j-rpc:
registry:
model: zookeeper # 目前仅支持 zookeeper
inet: 127.0.0.1 # 本机ip, 获取本机ip优先级 inet>inet-env>InetAddress.getLocalHost().getHostAddress()>127.0.0.1
inet-env: LOCAL_IP # 本级ip环境变量key
zookeeper:
address: 127.0.0.1:2181 # zk 地址 ,优先级 address>address-env>127.0.0.1:2181
address-env : ZK_ADDR # zk 地址环境变量
namespace: /com.github.jingshouyan.jrpc # 服务注册的namespace
session-timeout: 20000 #
connection-timeout: 5000 #
retry-interval-ms: 5000 #
client:
connect: #
timeout: 5000
pool: # 连接池配置
min-idle: 10
max-idle: 50
max-total: 200
3. 使用方法1
public class Test
{
@Resource
private JrpcClient jrpcClient;
public void test2(){
IdQuery idQuery = new IdQuery();
idQuery.setName("zhangsan");
idQuery.setAge(77);
idQuery.setIds(Lists.newArrayList("123","345"));
Token token = new Token();
Rsp rsp = Request.newInstance()
.setClient(jrpcClient) //设置发送客户端
.setServer("test") //调用的服务名
.setVersion("2.0") //服务的版本号
// .setInstance("test-111") //服务实例名,多个实例可以指定发送到对应的服务,没找到会有相应的错误码
.setMethod("getUserInfo") //服务方法名
.setToken(token) // 设置token ,可选 token 信息
.setParamObj(idQuery) //请求参数对象,也可以使用 setParamJson 直接设置json字符串
//.setOneway(true) //是否为 oneway 调用,
//asyncSend() 得到 Single<Rsp> 对象,异步调用模式
.send() //发送请求,这时已经得到 Rsp 对象
.checkSuccess(); //检查 返回码,不为 SUCCESS 则抛出异常
List<UserBean> userBeans = rsp.list(UserBean.class); //rsp中result实际为json字符串.list为将json反序列化为 List对象
List<UserBean> userBeans1 = rsp.get(List.class,UserBean.class); //也可以使用 get 带泛型的反序列化
}
}
使用方法2
添加 @EnableJrpcServices 注解
@SpringBootApplication
@EnableJrpcServices
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
编写服务接口
@JrpcService(server = "test", version = "1.0")
public interface TestService {
void traceTest2(Token token, int i);
Rsp asyncErr(Token token, String abc);
String asyncTest(Token token, String abc);
Mono<Void> myMethod(Token token, Object abc);
Mono<Object> testMethod(Token token, List<String> abc);
Mono<Rsp> traceTest(Token token, int i);
Mono<InterfaceInfo> getServerInfo(Token token, Object obj);
}
必须添加 @JrpcService 注解, server,version 为对应服务名&版本号.
方法名为对应接口名,参数0 必须是 Token,参数1 接口入参,参考Method.action,参数3可选 指定实例名
返回值类型void 不关心结果,不关心调用是否出错.
Rsp 得到 Rsp 响应.
其他类型 将 Rsp 中 result 转换成对应类型的结果,如果请求失败,抛出 JException 异常.
Mono<Void> 不建议使用,使用Mono代替.
Mono<Rsp> 响应式编程对象.
Mono<其他类型> 将 Rsp 中 result 转换成对应类型的结果,如果请求失败,在mono线程中抛出 JException 异常.
@Autowired 注入对象
public class ServiceTest {
@Autowired
private TestService testService;
}
接口转发模块
1. 引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-forward</artifactId>
<version>${jrpc-version}</version>
</dependency>
2. 添加 spring 配置信息
j-rpc:
forward:
methods: #格式: 本服务方法名: 转发服务名,对应方法名
forwardTest: test,testMethod
forwardTest2: test2,testMethod
zipkin 集成
1. 引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-trace-zipkin</artifactId>
<version>${jrpc-version}</version>
</dependency>
2. 添加 spring 配置信息
j-rpc:
trace:
name: trace-xxx # 链路名称,可选,若无取 jrpc.server.name 或 spring.application.name
endpoint: http://127.0.0.1:9411/api/v2/spans # zipkin 接口地址
rate: 0.1 # 采样率 0 ~ 1
dataShow: 0 # 请求参数&响应数据采集模式, 0: 不采集,1: 接口返回错误时采集,2:采集
3. 字节码注入
# 启动时注入 TransmittableThreadLocal
# 主要用于使用线程池和forkjoin框架时 span 信息传递
java -javaagent:path/to/transmittable-thread-local-2.x.x.jar -jar test-server.jar
数据脱敏
1. 引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-desensitize</artifactId>
<version>${jrpc-version}</version>
</dependency>
2. 添加 spring 配置信息
j-rpc:
desensitize:
settings:
name: 203 # key 为 name,且值为String类型的字段,除开头2位结尾3位,其他以 * 替换
查询接口
引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-dql</artifactId>
<version>${jrpc-version></version>
</dependency>
retrieve 方法自动注册到服务
client 调用
增删改接口
1.引入pom
<dependency>
<groupId>com.github.jingshouyan</groupId>
<artifactId>j-rpc-starter-dml</artifactId>
<version>${jrpc-version></version>
</dependency>
create 方法自动注册到服务
update 方法自动注册到服务
delete 方法自动注册到服务
2. 添加 spring 配置信息
j-rpc:
server:
plugin:
crud:
create: * # * 表示允许全部,默认为 * ,将所有dao 的 insert/batchInsert 方法暴露到服务
update: user,account # userDao, accountDao 的 update/batchUpdate 方法暴露到服务
delete: user # userDao 的 delete/delete4List 方法暴露到服务