Springcloud+consul作为微服务的注册已经见怪不怪了,试下也很流行,在我个人云服务器上,我也是这样做的。
然而,我的云服务器内存比较小,很快内存就被cloud全家桶吃光了,没办法部署其他应用了,因此,我觉得将一些服务独立出去,放弃cloud全家桶。
Consul-proxy使用netty+consul实现服务注册发现,并提供了若干简单的注解实现了http的mapping映射处理。
同时,在2.0版本中,增加了ribbon作为负载均衡策略选择consul中的服务,okhttp或httpclient或者自定义http工具做了客户端进行http请求。
jar包已经上传到maven中央仓库。 https://search.maven.org/search?q=consul-proxy ,groupId为cn.pomit。
<dependency>
<groupId>cn.pomit</groupId>
<artifactId>consul-proxy</artifactId>
<version>2.0</version>
</dependency>
使用注解@JsonServer启动,可以指定端口和handler处理逻辑。
@JsonServer(handler=AlarmHandler.class)
public class AlarmApp {
public static void main(String[] args) {
ConsulProxyApplication.run(AlarmApp.class);
}
}
若使用mybatis-proxy,可以如下启动:
@JsonServer(handler=AlarmHandler.class)
@EnableMybatis(mapperScan = "cn.pomit.alarm.mapper")
public class AlarmApp {
public static void main(String[] args) {
ConsulProxyApplication.run(AlarmApp.class);
}
}
若需要将属性传递给某个类进行初始化,可以在启动类上加上:
import cn.pomit.consul.ConsulProxyApplication;
import cn.pomit.consul.annotation.EnableServer;
import cn.pomit.consul.annotation.InitConfiguration;
import cn.pomit.serv.config.DataSourceConfiguration;
import cn.pomit.serv.config.MailConfiguration;
import cn.pomit.serv.handler.AdviceHandler;
import cn.pomit.serv.handler.EmailRestHandler;
@EnableServer(handler = { EmailRestHandler.class,AdviceHandler.class })
@InitConfiguration(configurations = { DataSourceConfiguration.class })
public class ServiceApp {
public static void main(String[] args) {
ConsulProxyApplication.run(ServiceApp.class, args);
}
}
这里,新建了个DataSourceConfiguration,用户替换mybatis的数据源,因此就不需要使用EnableMybatis注解了。
DataSourceConfiguration需要配置Mybatis初始化,调用MybatisConfiguration.initConfiguration进行初始化。
DataSourceConfiguration:
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import cn.pomit.mybatis.configuration.MybatisConfiguration;
public class DataSourceConfiguration {
public static final String DATASOURCE_PREFIX = "datasource.";
public static void initConfiguration(Properties properties) {
String packageName = "cn.pomit.serv.mapper";
try {
Properties dataSourceProperties = new Properties();
for (Object key : properties.keySet()) {
String tmpKey = key.toString();
if(tmpKey.startsWith(DATASOURCE_PREFIX)){
String datasourceKey = tmpKey.replace(DATASOURCE_PREFIX, "");
dataSourceProperties.put(datasourceKey, properties.get(key));
}
}
DataSource dataSource = BasicDataSourceFactory.createDataSource(dataSourceProperties);
MybatisConfiguration.initConfiguration(packageName, dataSource);
} catch (Exception e) {
e.printStackTrace();
MybatisConfiguration.initConfiguration(packageName, properties);
}
}
}
若要进行服务调用,需要在启动类上加上@EnableDiscovery注解:
package cn.pomit.consulproxy;
import cn.pomit.consul.ConsulProxyApplication;
import cn.pomit.consul.annotation.EnableDiscovery;
import cn.pomit.consul.annotation.EnableServer;
import cn.pomit.consul.annotation.InitConfiguration;
import cn.pomit.consulproxy.config.MailConfiguration;
import cn.pomit.consulproxy.handler.EmailRestHandler;
import cn.pomit.consulproxy.handler.GetTestHandler;
import cn.pomit.consulproxy.handler.PostTestHandler;
import cn.pomit.consulproxy.handler.RibbonRestHandler;
@EnableDiscovery
@EnableServer(handler = { EmailRestHandler.class, RibbonRestHandler.class, GetTestHandler.class,
PostTestHandler.class })
@InitConfiguration(configurations = { MailConfiguration.class })
public class ConsulApp {
public static void main(String[] args) {
ConsulProxyApplication.run(ConsulApp.class, args);
}
}
详细请查看ConsulProxy的服务调用。
继承AbstractResourceHandler的handler可以实现业务逻辑。
handler中可以使用Value注解进行属性注入:
@Value("api.gateway.kongUrl")
private String apiGatewayKongUrl;
handler中可以使用Mapping注解进行路径映射:
@Mapping("/alarm/gateway")
可以在命令行使用server.port。
可以使用spring.profiles.active或者profiles.active指定多个配置文件。
InitConfiguration注解放在启动类上,用来将属性传递给某个类进行初始化。
如:
import cn.pomit.consul.ConsulProxyApplication;
import cn.pomit.consul.annotation.EnableServer;
import cn.pomit.consul.annotation.InitConfiguration;
import cn.pomit.serv.config.DataSourceConfiguration;
import cn.pomit.serv.config.MailConfiguration;
import cn.pomit.serv.handler.AdviceHandler;
import cn.pomit.serv.handler.EmailRestHandler;
@EnableServer(handler = { EmailRestHandler.class,AdviceHandler.class })
@InitConfiguration(configurations = { DataSourceConfiguration.class })
public class ServiceApp {
public static void main(String[] args) {
ConsulProxyApplication.run(ServiceApp.class, args);
}
}
详情请查看ConsulProxy的initconfiguration
使用EnableMybatis注解放在启动类上,用来加载myabtis-proxy组件。myabtis-proxy是快速启动mybatis的一个组件。
详情请查看ConsulProxy的EnableMybatis
使用EnableDiscovery注解放在启动类上,用来支持注册到Consul的服务调用。使用ribbon做负载均衡。默认选择okhttp做http请求,同时内置httpclient并支持自定义http工具。
详细请查看ConsulProxy的服务调用。
调用demo项目中的hosts接口对cloud和netty进行对比
cloud和netty最大连接数分别设置为10000,最大线程数设置为200.
对比结果如下:
内存 | |
---|---|
cloud | 185m |
netty | 117m |
采样值 | 平均时间 | 偏离 | 异常率 | |
---|---|---|---|---|
cloud | 1000 | 3128 | 1888 | 0 |
netty | 1000 | 2215 | 2072 | 0 |
cloud | 3000 | 3416 | 2882 | 0 |
netty | 3000 | 1925 | 1647 | 0 |
cloud | 20000 | 15653 | 7591 | 0.50605 |
netty | 20000 | 11737 | 7076 | 0.2289 |
启动:
package cn.pomit.alarm;
import cn.pomit.alarm.handler.FalconAlarmHandler;
import cn.pomit.alarm.handler.GatewayAlarmHandler;
import cn.pomit.consul.ConsulProxyApplication;
import cn.pomit.consul.annotation.EnableServer;
@EnableServer(handler={FalconAlarmHandler.class,GatewayAlarmHandler.class})
public class AlarmApp {
public static void main(String[] args) {
ConsulProxyApplication.run(AlarmApp.class);
}
}
handler:
public class GatewayAlarmHandler extends AbstractResourceHandler {
@Value("api.gateway.kongUrl")
private String apiGatewayKongUrl;
@Value("api.gateway.appKey")
private String apiGatewayAppKey;
@Value("api.gateway.appSecret")
private String apiGatewayAppSecret;
@Mapping("/alarm/gateway")
public HttpResponseMessage gateway(HttpRequestMessage httpRequestMessage) {
try {
log.info("apiGatewayAppSecret: " + apiGatewayAppSecret + ", apiGatewayAppKey: " + apiGatewayAppKey);
ApiGatewayClient apiGatewayClient = new ApiGatewayClient.Builder().kongUrl(apiGatewayKongUrl)
.appKey(apiGatewayAppKey).appSecret(apiGatewayAppSecret).client(HttpClientPrototype.getHttpClient())
.build();
ApiGatewayService apiGatewayService = new ApiGatewayService(apiGatewayClient);
ResultModel resultModel = apiGatewayService.getAlarmInfo(null);
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.setResCode(ResCode.OK.getValue());
httpResponseMessage.setResType(ResType.JSON.getValue());
httpResponseMessage.setMessage(JSONObject.toJSONString(resultModel));
return httpResponseMessage;
} catch (Exception e) {
e.printStackTrace();
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.setResCode(ResCode.OK.getValue());
httpResponseMessage.setResType(ResType.JSON.getValue());
httpResponseMessage.setMessage(JSONObject.toJSONString(ResultModel.error("请求API网关失败")));
return httpResponseMessage;
}
}
@Mapping("/health")
public HttpResponseMessage health(HttpRequestMessage httpRequestMessage) {
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.setResCode(ResCode.OK.getValue());
httpResponseMessage.setResType(ResType.TEXT.getValue());
httpResponseMessage.setMessage("操作成功!");
return httpResponseMessage;
}
public String getApiGatewayKongUrl() {
return apiGatewayKongUrl;
}
public void setApiGatewayKongUrl(String apiGatewayKongUrl) {
this.apiGatewayKongUrl = apiGatewayKongUrl;
}
public String getApiGatewayAppKey() {
return apiGatewayAppKey;
}
public void setApiGatewayAppKey(String apiGatewayAppKey) {
this.apiGatewayAppKey = apiGatewayAppKey;
}
public String getApiGatewayAppSecret() {
return apiGatewayAppSecret;
}
public void setApiGatewayAppSecret(String apiGatewayAppSecret) {
this.apiGatewayAppSecret = apiGatewayAppSecret;
}
}
版本是向下兼容的,但为免混淆,demo项目区分开。
consul-proxy使用 Apache License 2.0 协议.
作者博客:https://blog.csdn.net/feiyangtianyao
个人网站:https://www.pomit.cn
作者邮箱: fufeixiaoyu@163.com
Apache License V2
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型