vertx网关支持唯一rpc uri, 客户端统一调用
This commit is contained in:
parent
e812d6dbf8
commit
9e0ec6ed28
@ -3,6 +3,7 @@ package com.sf.vertx.handle;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -15,6 +16,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
import com.alibaba.fastjson2.TypeReference;
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
import com.hazelcast.config.Config;
|
import com.hazelcast.config.Config;
|
||||||
import com.hazelcast.config.JoinConfig;
|
import com.hazelcast.config.JoinConfig;
|
||||||
|
import com.hazelcast.config.ManagementCenterConfig;
|
||||||
import com.hazelcast.config.NetworkConfig;
|
import com.hazelcast.config.NetworkConfig;
|
||||||
import com.hazelcast.config.TcpIpConfig;
|
import com.hazelcast.config.TcpIpConfig;
|
||||||
import com.sf.vertx.api.pojo.ApiConfig;
|
import com.sf.vertx.api.pojo.ApiConfig;
|
||||||
@ -40,9 +42,11 @@ import io.vertx.core.Future;
|
|||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.core.VertxOptions;
|
import io.vertx.core.VertxOptions;
|
||||||
import io.vertx.core.http.HttpClient;
|
import io.vertx.core.http.HttpClient;
|
||||||
|
import io.vertx.core.http.HttpMethod;
|
||||||
import io.vertx.core.http.HttpServer;
|
import io.vertx.core.http.HttpServer;
|
||||||
import io.vertx.core.http.HttpServerOptions;
|
import io.vertx.core.http.HttpServerOptions;
|
||||||
import io.vertx.core.spi.cluster.ClusterManager;
|
import io.vertx.core.spi.cluster.ClusterManager;
|
||||||
|
import io.vertx.ext.web.Route;
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
import io.vertx.httpproxy.HttpProxy;
|
import io.vertx.httpproxy.HttpProxy;
|
||||||
@ -62,6 +66,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
public class AppConfigHandler {
|
public class AppConfigHandler {
|
||||||
private static VertxConfig VERTX_CONFIG = new VertxConfig();
|
private static VertxConfig VERTX_CONFIG = new VertxConfig();
|
||||||
public static Vertx VERTX;
|
public static Vertx VERTX;
|
||||||
|
private static SacVertxConfig sacVertxConfig;
|
||||||
|
private static RedisTemplate<String, String> redisTemplate;
|
||||||
public static CircuitBreaker CONNECTION_CIRCUIT_BREAKER;
|
public static CircuitBreaker CONNECTION_CIRCUIT_BREAKER;
|
||||||
// global cache app config
|
// global cache app config
|
||||||
private static final ConcurrentHashMap<String, AppConfig> CACHE_APP_CONFIG_MAP = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<String, AppConfig> CACHE_APP_CONFIG_MAP = new ConcurrentHashMap<>();
|
||||||
@ -82,6 +88,14 @@ public class AppConfigHandler {
|
|||||||
// 禁用appCode
|
// 禁用appCode
|
||||||
private static ConcurrentHashSet<String> DISABLED_APPCODE = new ConcurrentHashSet<String>();
|
private static ConcurrentHashSet<String> DISABLED_APPCODE = new ConcurrentHashSet<String>();
|
||||||
|
|
||||||
|
public static Integer requestModel() {
|
||||||
|
return sacVertxConfig.getRequestModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String rpcUri() {
|
||||||
|
return sacVertxConfig.getRpcUri();
|
||||||
|
}
|
||||||
|
|
||||||
public static void addDisabledAppcode(String appCode) {
|
public static void addDisabledAppcode(String appCode) {
|
||||||
DISABLED_APPCODE.add(appCode);
|
DISABLED_APPCODE.add(appCode);
|
||||||
}
|
}
|
||||||
@ -98,6 +112,11 @@ public class AppConfigHandler {
|
|||||||
return CACHE_APP_CONFIG_MAP.get(appCode);
|
return CACHE_APP_CONFIG_MAP.get(appCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void init(RedisTemplate<String, String> _redisTemplate, SacVertxConfig _sacVertxConfig) {
|
||||||
|
redisTemplate = _redisTemplate;
|
||||||
|
sacVertxConfig = _sacVertxConfig;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isDataSecurity(String appCode) {
|
public static boolean isDataSecurity(String appCode) {
|
||||||
return CACHE_APP_CONFIG_MAP.get(appCode) != null && CACHE_APP_CONFIG_MAP.get(appCode).getDataSecurity() != null
|
return CACHE_APP_CONFIG_MAP.get(appCode) != null && CACHE_APP_CONFIG_MAP.get(appCode).getDataSecurity() != null
|
||||||
? true
|
? true
|
||||||
@ -194,17 +213,17 @@ public class AppConfigHandler {
|
|||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static void initAllAppConfig(RedisTemplate<String, String> redisTemplate) {
|
public static void initAllAppConfig() {
|
||||||
Set<String> set = redisTemplate.opsForZSet().range(RedisKeyConfig.APP_CONFIG_SET_KEY, 0, -1);
|
Set<String> set = redisTemplate.opsForZSet().range(RedisKeyConfig.APP_CONFIG_SET_KEY, 0, -1);
|
||||||
for (String appCode : set) {
|
for (String appCode : set) {
|
||||||
AppConfigHandler.initAppConfig(redisTemplate, appCode, false);
|
AppConfigHandler.initAppConfig(appCode, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* 加载vertx配置
|
* 加载vertx配置
|
||||||
*/
|
*/
|
||||||
public static void initVertxConfig(RedisTemplate<String, String> redisTemplate) {
|
public static void initVertxConfig() {
|
||||||
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
||||||
String vertxConfigValue = redisTemplate.opsForValue().get(vertxConfigKey);
|
String vertxConfigValue = redisTemplate.opsForValue().get(vertxConfigKey);
|
||||||
if (StringUtils.isNotBlank(vertxConfigValue)) {
|
if (StringUtils.isNotBlank(vertxConfigValue)) {
|
||||||
@ -239,8 +258,7 @@ public class AppConfigHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initAppConfig(RedisTemplate<String, String> redisTemplate, String appCode,
|
public static void initAppConfig(String appCode, boolean isDelLocalCache) {
|
||||||
boolean isDelLocalCache) {
|
|
||||||
// 是否需要先删除
|
// 是否需要先删除
|
||||||
if (isDelLocalCache) {
|
if (isDelLocalCache) {
|
||||||
delAppConfigCache(appCode);
|
delAppConfigCache(appCode);
|
||||||
@ -347,14 +365,14 @@ public class AppConfigHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createVertx(RedisTemplate<String, String> redisTemplate, SacVertxConfig sacVertxConfig) {
|
public static void createVertx() {
|
||||||
// TODO 编解码线程池,后面优化协程等方式
|
// TODO 编解码线程池,后面优化协程等方式
|
||||||
VertxOptions vertxOptions = new VertxOptions();
|
VertxOptions vertxOptions = new VertxOptions();
|
||||||
loadVertxOptions(vertxOptions);
|
loadVertxOptions(vertxOptions);
|
||||||
VERTX = Vertx.vertx(vertxOptions);
|
VERTX = Vertx.vertx(vertxOptions);
|
||||||
|
|
||||||
initConnectionCircuitBreaker();
|
initConnectionCircuitBreaker();
|
||||||
createVertxRouter(VERTX, redisTemplate, sacVertxConfig.getPort());
|
createVertxRouter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Config hazelcastConfig(SacVertxConfig sacVertxConfig) {
|
private static Config hazelcastConfig(SacVertxConfig sacVertxConfig) {
|
||||||
@ -376,16 +394,15 @@ public class AppConfigHandler {
|
|||||||
hazelcastConfig.setNetworkConfig(networkConfig);
|
hazelcastConfig.setNetworkConfig(networkConfig);
|
||||||
|
|
||||||
// TODO 还有问题,不会使用
|
// TODO 还有问题,不会使用
|
||||||
// ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig();
|
ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig();
|
||||||
// Set<String> interfaces = new HashSet<>();
|
Set<String> interfaces = new HashSet<>();
|
||||||
// interfaces.add("http://192.168.1.68:8080/mancenter");
|
interfaces.add("http://192.168.1.68:8080/mancenter");
|
||||||
// managementCenterConfig.setTrustedInterfaces(interfaces);
|
managementCenterConfig.setTrustedInterfaces(interfaces);
|
||||||
// hazelcastConfig.setManagementCenterConfig(managementCenterConfig);
|
hazelcastConfig.setManagementCenterConfig(managementCenterConfig);
|
||||||
return hazelcastConfig;
|
return hazelcastConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vertx createHazelcastClusterVertx(RedisTemplate<String, String> redisTemplate,
|
public static Vertx createHazelcastClusterVertx() {
|
||||||
SacVertxConfig sacVertxConfig) {
|
|
||||||
Config hazelcastConfig = hazelcastConfig(sacVertxConfig);
|
Config hazelcastConfig = hazelcastConfig(sacVertxConfig);
|
||||||
ClusterManager hazelcastClusterManager = new HazelcastClusterManager(hazelcastConfig);
|
ClusterManager hazelcastClusterManager = new HazelcastClusterManager(hazelcastConfig);
|
||||||
// TODO 编解码线程池,后面优化协程等方式
|
// TODO 编解码线程池,后面优化协程等方式
|
||||||
@ -397,7 +414,7 @@ public class AppConfigHandler {
|
|||||||
VERTX = res.result();
|
VERTX = res.result();
|
||||||
log.info("hazelcastClusterManager create success");
|
log.info("hazelcastClusterManager create success");
|
||||||
initConnectionCircuitBreaker();
|
initConnectionCircuitBreaker();
|
||||||
createVertxRouter(VERTX, redisTemplate, sacVertxConfig.getPort());
|
createVertxRouter();
|
||||||
// 订阅消息
|
// 订阅消息
|
||||||
VERTX.eventBus().consumer("sac_cluster_event", message -> {
|
VERTX.eventBus().consumer("sac_cluster_event", message -> {
|
||||||
if (message.body() != null) {
|
if (message.body() != null) {
|
||||||
@ -407,7 +424,7 @@ public class AppConfigHandler {
|
|||||||
if (msg.getType() == 1) {
|
if (msg.getType() == 1) {
|
||||||
if (msg.getOperation() == 1) {
|
if (msg.getOperation() == 1) {
|
||||||
// 初始化AppConfig本地缓存
|
// 初始化AppConfig本地缓存
|
||||||
AppConfigHandler.initAppConfig(redisTemplate, msg.getAppCode(), true);
|
AppConfigHandler.initAppConfig(msg.getAppCode(), true);
|
||||||
} else if (msg.getOperation() == 3) {
|
} else if (msg.getOperation() == 3) {
|
||||||
// 禁用本地缓存
|
// 禁用本地缓存
|
||||||
AppConfigHandler.addDisabledAppcode(msg.getAppCode());
|
AppConfigHandler.addDisabledAppcode(msg.getAppCode());
|
||||||
@ -432,22 +449,21 @@ public class AppConfigHandler {
|
|||||||
VERTX.eventBus().publish("sac_cluster_event", JSONObject.toJSONString(msg));
|
VERTX.eventBus().publish("sac_cluster_event", JSONObject.toJSONString(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createVertxRouter(Vertx vertx, RedisTemplate<String, String> redisTemplate,
|
private static void createVertxRouter() {
|
||||||
Integer serverDefaultPort) {
|
|
||||||
// consul初始化
|
// consul初始化
|
||||||
// ConsulHandler.init(vertx);
|
// ConsulHandler.init(vertx);
|
||||||
// ConsulHandler.init1(vertx);
|
// ConsulHandler.init1(vertx);
|
||||||
|
|
||||||
// 从redis同步app配置
|
// 从redis同步app配置
|
||||||
initAllAppConfig(redisTemplate);
|
initAllAppConfig();
|
||||||
|
|
||||||
VertxConfig vertxConfig = AppConfigHandler.getVertxConfig();
|
VertxConfig vertxConfig = AppConfigHandler.getVertxConfig();
|
||||||
// 创建HTTP监听
|
// 创建HTTP监听
|
||||||
// 所有ip都能访问
|
// 所有ip都能访问
|
||||||
HttpServerOptions httpServerOptions = new HttpServerOptions().setHost("0.0.0.0");
|
HttpServerOptions httpServerOptions = new HttpServerOptions().setHost("0.0.0.0");
|
||||||
HttpServer server = vertx.createHttpServer(httpServerOptions);
|
HttpServer server = VERTX.createHttpServer(httpServerOptions);
|
||||||
Router mainHttpRouter = Router.router(vertx);
|
Router mainHttpRouter = Router.router(VERTX);
|
||||||
Integer serverPort = vertxConfig.getPort() == null ? serverDefaultPort : vertxConfig.getPort();
|
Integer serverPort = vertxConfig.getPort() == null ? sacVertxConfig.getPort() : vertxConfig.getPort();
|
||||||
log.info("serverPort:{}", serverPort);
|
log.info("serverPort:{}", serverPort);
|
||||||
server.requestHandler(mainHttpRouter).listen(serverPort, h -> {
|
server.requestHandler(mainHttpRouter).listen(serverPort, h -> {
|
||||||
if (h.succeeded()) {
|
if (h.succeeded()) {
|
||||||
@ -463,7 +479,7 @@ public class AppConfigHandler {
|
|||||||
// clientOptions.setHttp2KeepAliveTimeout(1);
|
// clientOptions.setHttp2KeepAliveTimeout(1);
|
||||||
// clientOptions.setIdleTimeout(1000); // 连接空闲超时 毫秒
|
// clientOptions.setIdleTimeout(1000); // 连接空闲超时 毫秒
|
||||||
// HttpClient proxyClient = VERTX.createHttpClient(clientOptions);
|
// HttpClient proxyClient = VERTX.createHttpClient(clientOptions);
|
||||||
HttpClient proxyClient = vertx.createHttpClient();
|
HttpClient proxyClient = VERTX.createHttpClient();
|
||||||
HttpProxy proxy = HttpProxy.reverseProxy(proxyClient);
|
HttpProxy proxy = HttpProxy.reverseProxy(proxyClient);
|
||||||
proxy.originSelector(request -> Future.succeededFuture(ProxyTool.resolveOriginAddress(request)));
|
proxy.originSelector(request -> Future.succeededFuture(ProxyTool.resolveOriginAddress(request)));
|
||||||
proxy.addInterceptor(new ProxyInterceptor() {
|
proxy.addInterceptor(new ProxyInterceptor() {
|
||||||
@ -473,6 +489,16 @@ public class AppConfigHandler {
|
|||||||
// // 会跳转到 RestfulFailureHandlerImpl
|
// // 会跳转到 RestfulFailureHandlerImpl
|
||||||
// throw new HttpException(10003);
|
// throw new HttpException(10003);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (AppConfigHandler.requestModel() == 2) {
|
||||||
|
String appCode = context.request().headers().get(getAppCodeHeaderKey());
|
||||||
|
String apiCode = context.request().headers().get(getApiCodeHeaderKey());
|
||||||
|
String key = appCode + ":" + apiCode;
|
||||||
|
String uri = APICODE_CONFIG_MAP.get(key).getUri();
|
||||||
|
String method = APICODE_CONFIG_MAP.get(key).getMethod();
|
||||||
|
context.request().setURI(uri).setMethod(HttpMethod.valueOf(method));
|
||||||
|
}
|
||||||
|
|
||||||
return context.sendRequest();
|
return context.sendRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,11 +513,17 @@ public class AppConfigHandler {
|
|||||||
return context.sendResponse();
|
return context.sendResponse();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
WebClient mainWebClient = WebClient.create(vertx);
|
WebClient mainWebClient = WebClient.create(VERTX);
|
||||||
|
|
||||||
String rateLimitModel = vertxConfig.getRateLimitModel();
|
String rateLimitModel = vertxConfig.getRateLimitModel();
|
||||||
rateLimitModel = "local";
|
rateLimitModel = "local";
|
||||||
mainHttpRouter.route().handler(ParameterCheckHandler.create())
|
Route route = null;
|
||||||
|
if (requestModel() == 2) {
|
||||||
|
route = mainHttpRouter.route(rpcUri());
|
||||||
|
} else {
|
||||||
|
route = mainHttpRouter.route();
|
||||||
|
}
|
||||||
|
route.handler(ParameterCheckHandler.create())
|
||||||
.handler(AppRateLimitHandler.create(rateLimitModel)).handler(ApiRateLimitHandler.create(rateLimitModel))
|
.handler(AppRateLimitHandler.create(rateLimitModel)).handler(ApiRateLimitHandler.create(rateLimitModel))
|
||||||
.handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient, proxy))
|
.handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient, proxy))
|
||||||
.failureHandler(RestfulFailureHandler.create());
|
.failureHandler(RestfulFailureHandler.create());
|
||||||
|
@ -28,9 +28,10 @@ public class ParameterCheckHandlerImpl implements ParameterCheckHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 通过请求模式来区分
|
||||||
String uri = rc.request().uri();
|
String uri = rc.request().uri();
|
||||||
String httpMethod = rc.request().method().name();
|
String httpMethod = rc.request().method().name();
|
||||||
if(AppConfigHandler.isApicodeUri(key, uri, httpMethod) == false) {
|
if(AppConfigHandler.requestModel() == 1 && AppConfigHandler.isApicodeUri(key, uri, httpMethod) == false) {
|
||||||
rc.fail(new HttpException(10018));
|
rc.fail(new HttpException(10018));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,9 @@ public class DynamicBuildServer implements ApplicationRunner {
|
|||||||
public void run(ApplicationArguments args) throws Exception {
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
// 初始化redis key
|
// 初始化redis key
|
||||||
redisKeyConfig.init();
|
redisKeyConfig.init();
|
||||||
|
AppConfigHandler.init(redisTemplate, sacVertxConfig);
|
||||||
// 从redis同步vertx配置
|
// 从redis同步vertx配置
|
||||||
AppConfigHandler.initVertxConfig(redisTemplate);
|
AppConfigHandler.initVertxConfig();
|
||||||
|
|
||||||
// 加载vertx、应用配置
|
// 加载vertx、应用配置
|
||||||
startVertxService();
|
startVertxService();
|
||||||
@ -50,9 +51,9 @@ public class DynamicBuildServer implements ApplicationRunner {
|
|||||||
*/
|
*/
|
||||||
private void startVertxService() throws Exception {
|
private void startVertxService() throws Exception {
|
||||||
// 单机
|
// 单机
|
||||||
//AppConfigHandler.createVertx(redisTemplate, sacVertxConfig);
|
//AppConfigHandler.createVertx();
|
||||||
// 集群
|
// 集群
|
||||||
AppConfigHandler.createHazelcastClusterVertx(redisTemplate, sacVertxConfig);
|
AppConfigHandler.createHazelcastClusterVertx();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,12 @@ public class SacVertxConfig {
|
|||||||
@Value("${server.vertx.cluster.ip}")
|
@Value("${server.vertx.cluster.ip}")
|
||||||
private String clusterIp;
|
private String clusterIp;
|
||||||
|
|
||||||
|
@Value("${server.vertx.requestModel}")
|
||||||
|
private Integer requestModel;
|
||||||
|
|
||||||
|
@Value("${server.vertx.rpcUri}")
|
||||||
|
private String rpcUri;
|
||||||
|
|
||||||
@Value("${server.vertx.cluster.clusterName}")
|
@Value("${server.vertx.cluster.clusterName}")
|
||||||
private String clusterName;
|
private String clusterName;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public class AppConfigServiceImpl implements AppConfigService {
|
|||||||
public void saveVertxConfig(VertxConfig vertxConfig) {
|
public void saveVertxConfig(VertxConfig vertxConfig) {
|
||||||
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
|
||||||
redisTemplate.opsForValue().set(vertxConfigKey, JSONObject.toJSONString(vertxConfig));
|
redisTemplate.opsForValue().set(vertxConfigKey, JSONObject.toJSONString(vertxConfig));
|
||||||
AppConfigHandler.initVertxConfig(redisTemplate);
|
AppConfigHandler.initVertxConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
server:
|
server:
|
||||||
vertx:
|
vertx:
|
||||||
|
requestModel: 1 # 1: 客户端传递uri. 2: uri vertx代理,不对客户端暴露uri
|
||||||
|
rpcUri: /rpc
|
||||||
environment: dev
|
environment: dev
|
||||||
server:
|
server:
|
||||||
default:
|
default:
|
||||||
port: 80
|
port: 80
|
||||||
|
cluster:
|
||||||
|
ip: 192.168.1.68
|
||||||
|
clusterName: sac-dev
|
||||||
# 服务器的HTTP端口,默认为8080
|
# 服务器的HTTP端口,默认为8080
|
||||||
port: 5566
|
port: 5566
|
||||||
servlet:
|
servlet:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user