Api-gateway-center
# Api-gateway-center
# 1.网关服务注册库表设计
RPC接口:在设计上是一个明显的应用、接口、方法一对N的映射。
网关服务组:核心在于理解group_id和gateway_id。
①group_id:相当于抽象出的一个业务模块组,也可以是一个领域组。
②gateway_ip:对应一个网关通信实例gateway-core。
③在distribution分配表中,一个应用可以注册在多个网关通信实例,从而实现负载均衡。
④另一种设计方式distribution表中每个应用只需要注册在group_id组上,server_detail表中需要添加group_id字段指明当前通信实例属于哪个组。当HTTP请求过来时,根据应用名找到对应的服务组,然后均衡的打到该组下的每个服务实例当中。

# 2.结合Content-Type类型接收请求参数
@RequestParam:接收①get请求url中的参数②Post请求体中的json(仅支持Content-Type为form表单、www-form-unlencode类型)
@RequestBody:接收post请求体中的json数据(仅支持content-Type=application/json),用一个对象或者Map接收(一个请求对应只能用一个requestBody注解)。
# 3.网关算力与RPC接口注册
- 网关算力注册
ConfigManageService#registerGatewayServerNode:添加网关算力节点时,需要考虑节点重复注册的问题。因此需要先查数据库,如果节点还没注册,那么添加注册当前节点;否则更新当前算力节点为可用状态。
- RPC接口信息注册
将RPC应用、接口、方法信息在注册中心完成注册。
- 应用ID—接口ID—方法ID &&网关算力ID—网关算力地址
添加多列联合唯一约束(一张表可以有多个唯一索引,允许为空值),并建立B+树索引,更适用于范围查找(大于小于、覆盖索引(select字段建立了索引,保证where字段索引生效)、模糊查询)。
UNIQUE KEY `idx` (`system_id`,`interface_id`) USING BTREE
向表中插入数据后,如果表的联合唯一索引字段存在重复,就会报DuplicateKeyException异常 ,通过捕获该异常来监测所注册RPC服务与算力节点是否重复。
# 4.拉取RPC服务聚合信息
- 功能
①添加List属性封装当前网关映射的RPC聚合信息。
②网关助手assist-starter添加从注册中心拉取算力节点上的RPC注册信息,并打印出来。作为启动项目时打印给用户的日志信息。
③提取网关服务端配置到configution。当启动多个算力节点时,Netty服务IP和端口需要从文件读取配置。
- skipTests&maven.test.skip
install打包时不执行单元测试用例,但是会编译测试用例类生成的class文件到target/test-classes
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
2
3
4
5
6
7
maven.test.skip=true则表示不执行测试用例,也不编译测试用例类
- TypeReference
使用fastjson对String类型进行反序列化时,如果指定的类型含有泛型参数,那么需要使用TypeReference来解析。
# 5.算力节点与RPC服务映射查询
根据数据库的网关算力分配表,给后台提供网关分组—网关ID—RPC服务应用ID的关联映射关系查询的方法接口,它们是1vNvN的关系,具体groupId-->gatewayId-->systemId如下: 10001->api-gateway-g3->api-gateway-test-01-provider 10001->api-gateway-g3->api-gateway-test-02-provider 10001->api-gateway-g4->api-gateway-test-03-provider 10001->api-gateway-g4->api-gateway-test-04-provider 10002->api-gateway-g5->api-gateway-test-05-provider 10002->api-gateway-g5->api-gateway-test-06-provider
# 6.动态节点配置Nginx负载
功能:新的网关算力节点注册后,注册中心通过java程序编程式调用容器指令,将其动态配置Nginx网关负载。

- 容器配置文件挂载
gateway-center注册中心程序部署到容器运行,此时在容器内部不能感知到外部centos7服务器上的文件,因此通过new File()进行IO时只能操作容器内部的目录文件,不能直接对服务器上的文件进行读写。此处下面的文件地址为容器内部地址。
File file = new File("/nginx/conf/nginx.conf");
解决方案是运行容器时,通过-v将容器内部文件挂载到容器外部的Nginx配置文件,从而实现容器内部更新的IO内容同步到外部的Nginx配置文件。最终,运行注册中心程序的docker容器和运行Nginx服务器的docker容器两者挂载到同一个容器外部(服务器)的文件目录。
- 刷新配置生效
Nginx.conf配置文件改变之后,需要通过指令docker exec Nginx nginx -s reload重新刷新Nginx配置文件,使其生效。而两者处于不同的容器,需要通过com.github.dockerjava包工具建立docker连接,查找服务并执行指令(开启监听端口)。
跨容器调用服务的核心:通过ListContainersCmd#withNameFilter对容器名过滤,获取剩下的指定容器ID后,通过exec指令进入容器内部获取对应服务。
- 网关算力节点动态配置Nginx负载
要使用Nginx的负载均衡,需要将原本直接访问网关算力节点地址,改为访问Nginx中的location匹配路径。Nginx匹配到HTTP服务组后,先通过rewrite删除路径中的网关分组标识,然后将剩余内容拼接上代理服务器。
①^表示匹配输入字符串起始位置
②$表示匹配输入字符串的结束位置
③()用于匹配括号内的内容,此处表示匹配10001/后的所有内容,通过$1,$2调用
④下面例子表示,uri截取/10001/后面的内容进行重定向,并且结束下面所有的匹配规则。
rewrite ^/10001/(.*)$ /$1 break;
- Collectors#groupingBy
List集合通过stream流重新收集构造Map,groupingBy指定容器数据类型的哪个字段作为key,value为聚合的List集合。key->groupId,value->List<GatewayServerDetailVO>
Map<String, List<GatewayServerDetailVO>> gatewayServerDetailMap = gatewayServerDetailVOS.stream()
.collect(Collectors.groupingBy(GatewayServerDetailVO::getGroupId));
2