• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

consul-proxy: 使用netty+consul做服务注册和转发,替代springcloud+cunsul全家桶的臃 ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

consul-proxy

开源软件地址:

https://gitee.com/ffch/consul-proxy

开源软件介绍:

LicenseJDK 1.8Maven Central

Consul-proxy项目简介

Springcloud+consul作为微服务的注册已经见怪不怪了,试下也很流行,在我个人云服务器上,我也是这样做的。

然而,我的云服务器内存比较小,很快内存就被cloud全家桶吃光了,没办法部署其他应用了,因此,我觉得将一些服务独立出去,放弃cloud全家桶。

Consul-proxy使用netty+consul实现服务注册发现,并提供了若干简单的注解实现了http的mapping映射处理。

同时,在2.0版本中,增加了ribbon作为负载均衡策略选择consul中的服务,okhttp或httpclient或者自定义http工具做了客户端进行http请求。

Gitee

Github

Get Started

主要功能

  1. 快速启动。
  2. 映射路径。
  3. handler中的属性注入。
  4. 多handler支持,类似于spring的Controller。
  5. 支持springboot的server.port和spring.profiles.active多配置文件 (V1.1版本)
  6. 支持@EnableMybatis注解,快速使用mybatis(V1.2版本)
  7. 新增@InitConfiguration注解,注解在启动类上,将自动加载注解指定类的initConfiguration方法并传递属性文件。(V1.3版本)
  8. Netty在Json请求时,如果解析key-value参数会出现空指针异常,因此Json请求不再解析body的参数,直接返回body内容。(V1.3版本)
  9. 增加了服务发现及负载均衡http请求功能。使用ribbon + http工具(默认okhttp)进行负载均衡http请求。(V2.0版本)

使用说明

jar包已经上传到maven中央仓库。https://search.maven.org/search?q=consul-proxy ,groupId为cn.pomit。

使用文档地址

maven依赖

<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")

多配置文件(V1.1版本)

可以在命令行使用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

启用Mybatis

使用EnableMybatis注解放在启动类上,用来加载myabtis-proxy组件。myabtis-proxy是快速启动mybatis的一个组件。

详情请查看ConsulProxy的EnableMybatis

启用服务发现

使用EnableDiscovery注解放在启动类上,用来支持注册到Consul的服务调用。使用ribbon做负载均衡。默认选择okhttp做http请求,同时内置httpclient并支持自定义http工具。

详细请查看ConsulProxy的服务调用

性能测试

调用demo项目中的hosts接口对cloud和netty进行对比

cloud和netty最大连接数分别设置为10000,最大线程数设置为200.

对比结果如下:

内存
cloud185m
netty117m
采样值平均时间偏离异常率
cloud1000312818880
netty1000221520720
cloud3000341628820
netty3000192516470
cloud200001565375910.50605
netty200001173770760.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项目

版本是向下兼容的,但为免混淆,demo项目区分开。

2.0版本的demo项目

Gitee-Consul-proxy-demo-2.0

Github-Consul-proxy-demo-2.0

1.3 版本前的项目

Gitee-Consul-proxy-demo

Github-Consul-proxy-demo

Gitee-Consul-proxy-test

Github-Consul-proxy-test

Get-Started

版权声明

consul-proxy使用 Apache License 2.0 协议.

作者信息

作者博客:https://blog.csdn.net/feiyangtianyao

个人网站:https://www.pomit.cn

作者邮箱: [email protected]

License

Apache License V2


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap