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