15 Star 87 Fork 39

车江毅 / free-bsf-all

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 6.81 KB
一键复制 编辑 原始数据 按行查看 历史
chejiangyi 提交于 2022-12-15 16:41 . 2.2版本 文档完善

apiRegistry Api注册中心

简单的api注册中心,模拟eureka的实现原理实现,兼容旧feign的调用模式。支持服务故障转移,负载均衡,注册中心,rpc调用。整体代码简单,非常容易定制化改动。

技术说明

  • 支持HttpUrlConnection,HttpClient建立的连接池及扩展。
  • 支持轮训模式负载均衡及扩展。
  • 支持消费者端检测故障,临时转移到可用服务,待服务故障恢复后恢复调用。
  • 支持redis注册中心及扩展及无注册中心架构。
  • 支持protobuf协议,整体rpc性能会有较大提升。

设计及背景介绍文档

自研高性能分布式服务中心实践笔记

架构示意图

注册中心示意图

消费者rpc生命周期图

注册中心示意图

依赖引用

添加bsf模块到项目依赖中

<dependency>
	<artifactId>free-bsf-api</artifactId>
	<groupId>com.free.bsf</groupId>
	<version>2.2-SNAPSHOT</version>
</dependency>
<dependency>
	<artifactId>free-bsf-core</artifactId>
	<groupId>com.free.bsf</groupId>
	<version>2.2-SNAPSHOT</version>
</dependency>
<dependency>
	<artifactId>free-bsf-apiregistry</artifactId>
	<groupId>com.free.bsf</groupId>
	<version>2.2-SNAPSHOT</version>
</dependency>

入门篇

bsf配置

spring.application.name=free-demo-provider
#一键启用开关,默认false,重启后生效
bsf.apiRegistry.enabled=false

#支持ApiClient/FeignClient注解方式的Rpc拦截,重启后生效
bsf.apiRegistry.apiClientAspect.enabled=false

#rpc调用异常报警支持通知到飞书,钉钉等
bsf.apiRegistry.warn.enabled=false

#支持rpc多个服务强制制定路由,注意配置后相应服务的注册中心节点信息会失效不再使用,appName为服务名.
bsf.apiRegistry.{appName}.hosts=

#rpcClient的客户端实现,支持HttpUrlConnectionRpcClient,HttpClientRpcClient
bsf.apiRegistry.rpcClient.type=HttpUrlConnectionRpcClient

#rpcClient 扫描@ApiClient/@FeignClient注解的包,以逗号分割多个【rpc调用必填】
bsf.apiRegistry.rpcClient.basePackages=

#rpcClient 重命名beanName为类型全路径模式,解决bean注入时命名冲突问题
bsf.apiRegistry.rpcClient.typeBeanName.enabled=true

#rpcClient调用错误重试次数
bsf.apiRegistry.rcpClient.failRetryTimes=3

#rpcClient故障恢复重试间隔时间
bsf.apiRegistry.rcpClient.failRetryTimeSpan=30000

#httpUrlConnection rpcClient是否启动连接池
bsf.apiRegistry.rpcClient.httpUrlConnection.poolEnabled=true

#httpUrlConnection rpcClient 读取超时时间
bsf.apiRegistry.rpcClient.httpUrlConnection.readTimeOut=60000

#httpUrlConnection rpcClient 连接超时时间
bsf.apiRegistry.rpcClient.httpUrlConnection.connectTimeOut=3000

#注册中心实现,目前仅支持redis
bsf.apiRegistry.registry.type=RedisRegistry

#注册中心是否注册当前服务
bsf.apiRegistry.registry.clientRegistered=true

#注册中心redis实现的,redis地址格式:127.0.0.1:6379
bsf.apiRegistry.registry.redis.host=

#注册中心redis实现的,实例心跳上报时间
bsf.apiRegistry.registry.redis.heartBeatTime=3000

#注册中心redis过期时间,实例上报信息在redis里面的失效时间
bsf.apiRegistry.registry.redis.expireTime=5

#负载均衡器算法,目前仅支持RoundRobinLoadBalance
bsf.apiRegistry.loadBalance.type=RoundRobinLoadBalance

#编码方式,支持json和protobuf
bsf.apiRegistry.code.type=json

#注册中心健康检测模块,支持查看健康状态和下线服务
bsf.apiRegistry.health.enabled=true

############其他配置################
#可剔除服务注册时其他网段的ip,用于本地多网卡时的调试;参考bsf-core中的配置信息。格式:10.0.7.,192.168.
bsf.util.ip.exclude.regex=
bsf.util.ip.include.regex=

支持protobuf协议案例

#服务端开启protobuf(http输出支持协议解析,采用protostuff工具),根据header中Content-Type:application/x-protobuf触发
bsf.web.serialize.protostuff.enabled=false

#客户端rpc开启protobuf编码,开启后rpc 请求header中Content-Type会设置为application/x-protobuf
bsf.apiRegistry.code.type=protostuff

调用方式案例

//兼容@FeginClient
@ApiClient(name = "lmc-test-provider",path = "/")
public interface  CustomerProvider {
    /*接口协议定义*/
    //支持GetMapping,PostMapping
    @PostMapping("/test")
    //支持@RequestParam,@RequestBody
    ApiResponseEntity<String>  test(@RequestParam("str") String str);
}

@ApiIgnore忽略方法

//兼容@FeginClient
@ApiClient(name = "lmc-test-provider",path = "/")
public interface  CustomerProvider {
    /*使用接口默认实现*/
    @ApiIgnore
    default ApiResponseEntity<String>  skipMethod() {
        val result = HttpClientUtils.Default().get("http://www.baidu.com/");
        return ApiResponseEntity.success(result);
    }
}

CoreRequestInterceptor请求拦截器(类似feign请求拦截器)

public class ApiRegistryRequestInterceptor implements CoreRequestInterceptor {
    @Override
    public void append(RequestInfo request) {
        val header = newHeader();
        if(header!=null){
            for(val kv:header.entrySet()){
                request.getHeader().put(kv.getKey(),kv.getValue());
            }
        }
    }
}

开发人员访问注册中心列表

bsf.apiRegistry.health.enabled=true

以下三种方式,都可获取实时服务列表:

  1. 任意服务(消费者/生产者端)访问http://localhost:{本地端口}/bsf/apiRegistry/
  2. 类似eureka建立一个空服务做eureka server。
  3. 直接访问redis或者其他注册中心。

其他场景

兼容使用k8s自带负载均衡作为网关和转发(无注册中心)。

#支持rpc多个服务强制制定路由,注意配置后相应服务的注册中心节点信息会失效不再使用
bsf.apiRegistry.{appName}.hosts=
#注册中心实现,使用空注册中心实现
bsf.apiRegistry.registry.type=NoneRegistry

本地调试,注册到远程调试

bsf.util.ip.include.regex={本地ip}
bsf.apiRegistry.registry.clientRegistered=true

本地调试,联调远程特定服务,不注册自身服务

#支持rpc多个服务强制制定路由,注意配置后相应服务的注册中心节点信息会失效不再使用
bsf.apiRegistry.{appName}.hosts={远程iphost,如http://aaa/bbb/或127.0.0.1:8080}
bsf.apiRegistry.registry.clientRegistered=false

eureka注册中心无缝迁移(eureka和apiRegistry双注册中心同时使用)

#可以实现eureka和rpc同时调用,返回eureka调用结果,并核对rpc结果进行校验(不一致会报警),实现无缝稳定的迁移。
#支持eureka和rpc调用内部测试校验,仅临时使用
bsf.apiRegistry.test.enabled=false

#跳过部分rpc方法,支持前后*模糊匹配,支持逗号分割多个method,默认为空。
bsf.apiRegistry.test.skipMethods=

后续扩展

  1. 支持其他注册中心实现。

by 车江毅

Java
1
https://gitee.com/chejiangyi/free-bsf-all.git
git@gitee.com:chejiangyi/free-bsf-all.git
chejiangyi
free-bsf-all
free-bsf-all
2.2-SNAPSHOT

搜索帮助