Gateway集成Netty服务
Gateway和Netty都有盲区的感觉;
一、Netty简介
Netty是一个异步的,事件驱动的网络应用框架,用以快速开发高可靠、高性能的网络应用程序。

传输服务:提供网络传输能力的管理;
协议支持:支持常见的数据传输协议;
核心模块:包括可扩展事件模型、通用的通信API、零拷贝字节缓冲;
二、Netty入门案例
1、服务端启动
配置Netty服务器端程序,引导相关核心组件的加载;
public class NettyServer {
public static void main(String[] args) {
// EventLoop组,处理事件和IO
EventLoopGroup parentGroup = new NioEventLoopGroup();
EventLoopGroup childGroup = new NioEventLoopGroup();
try {
// 服务端启动引导类
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(parentGroup, childGroup)
.channel(NioServerSocketChannel.class).childHandler(new ChannelInit());
// 异步IO的结果
ChannelFuture channelFuture = serverBootstrap.bind(8082).sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e){
e.printStackTrace();
} finally {
parentGroup.shutdownGracefully();
childGroup.shutdownGracefully();
}
}
}
2、通道初始化
ChannelInitializer特殊的通道处理器,提供一种简单的方法,对注册到EventLoop的通道进行初始化;比如此处设置的编码解码器,自定义处理器;
public class ChannelInit extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) {
// 获取管道
ChannelPipeline pipeline = socketChannel.pipeline();
// Http编码、解码器
pipeline.addLast("DefHttpServerCodec",new HttpServerCodec());
// 添加自定义的handler
pipeline.addLast("DefHttpHandler", new DefHandler());
}
}
3、自定义处理器
处理对服务器端发起的访问,通常包括请求解析,具体的逻辑执行,请求响应等过程;
public class DefHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject message) throws Exception {
if(message instanceof HttpRequest) {
// 请求解析
HttpRequest httpRequest = (HttpRequest) message;
String uri = httpRequest.uri();
String method = httpRequest.method().name();
log.info("【HttpRequest-URI:"+uri+"】");
log.info("【HttpRequest-method:"+method+"】");
Iterator<Map.Entry<String,String>> iterator = httpRequest.headers().iteratorAsString();
while (iterator.hasNext()){
Map.Entry<String,String> entry = iterator.next();
log.info("【Header-Key:"+entry.getKey()+";Header-Value:"+entry.getValue()+"】");
}
// 响应构建
ByteBuf content = Unpooled.copiedBuffer("Netty服务", CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse
(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=utf-8");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(response);
}
}
}
4、测试请求
上面入门案例中,简单的配置了一个Netty服务器端,启动之后在浏览器中模拟访问即可;
http://127.0.0.1:8082/?id=1&name=Spring
三、Gateway集成
1、依赖层级
项目中Gateway网关依赖的版本为2.2.5.RELEASE,发现Netty依赖的版本为4.1.45.Final,是当下比较主流的版本;
<!-- 1、项目工程依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!-- 2、starter-gateway依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
<!-- 3、starter-webflux依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-reactor-netty</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
2、自动化配置
在Gateway网关的自动化配置配置类中,提供了Netty配置的管理;
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class,WebFluxAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HttpClient.class)
protected static class NettyConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.httpserver.wiretap")
public NettyWebServerFactoryCustomizer nettyServerWiretapCustomizer(
Environment environment, ServerProperties serverProperties) {
return new NettyWebServerFactoryCustomizer(environment, serverProperties) {
@Override
public void customize(NettyReactiveWebServerFactory factory) {
factory.addServerCustomizers(httpServer -> httpServer.wiretap(true));
super.customize(factory);
}
};
}
}
}
四、配置加载
1、基础配置
在工程的配置文件中,简单做一些基础性的设置;
server:
port: 8081 # 端口号
netty: # Netty组件
connection-timeout: 3000 # 连接超时
2、属性配置类
在ServerProperties类中,并没有提供很多显式的Netty配置参数,更多信息需要参考工厂类;
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
public static class Netty {
private Duration connectionTimeout;
}
}
3、配置加载分析

- 基于配置的属性,定制化管理Netty服务的信息;
public class NettyWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory>{
private final Environment environment;
private final ServerProperties serverProperties;
@Override
public void customize(NettyReactiveWebServerFactory factory) {
PropertyMapper propertyMapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
ServerProperties.Netty nettyProperties = this.serverProperties.getNetty();
propertyMapper.from(nettyProperties::getConnectionTimeout).whenNonNull()
.to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout));
}
}
- NettyReactiveWeb服务工厂,基于上述入门案例,创建WebServer时,部分参数信息出自LoopResources接口;
public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory {
private ReactorResourceFactory resourceFactory;
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
HttpServer httpServer = createHttpServer();
ReactorHttpHandlerAdapter handlerAdapter = new ReactorHttpHandlerAdapter(httpHandler);
NettyWebServer webServer = new NettyWebServer(httpServer, handlerAdapter, this.lifecycleTimeout);
webServer.setRouteProviders(this.routeProviders);
return webServer;
}
private HttpServer createHttpServer() {
HttpServer server = HttpServer.create();
if (this.resourceFactory != null) {
LoopResources resources = this.resourceFactory.getLoopResources();
server = server.tcpConfiguration(
(tcpServer) -> tcpServer.runOn(resources).addressSupplier(this::getListenAddress));
}
return applyCustomizers(server);
}
}
五、周期管理方法
1、控制类

Gateway项目中,Netty服务核心控制类,通过NettyReactiveWebServerFactory工厂类创建,对Netty生命周期的管理提供了一层包装;
public class NettyWebServer implements WebServer {
private final HttpServer httpServer;
private final ReactorHttpHandlerAdapter handlerAdapter;
/**
* 启动方法
*/
@Override
public void start() throws WebServerException {
if (this.disposableServer == null) {
this.disposableServer = startHttpServer();
// 控制台日志
logger.info("Netty started on port(s): " + getPort());
startDaemonAwaitThread(this.disposableServer);
}
}
private DisposableServer startHttpServer() {
HttpServer server = this.httpServer;
if (this.routeProviders.isEmpty()) {
server = server.handle(this.handlerAdapter);
}
return server.bindNow();
}
/**
* 停止方法
*/
@Override
public void stop() throws WebServerException {
if (this.disposableServer != null) {
// 释放资源
if (this.lifecycleTimeout != null) {
this.disposableServer.disposeNow(this.lifecycleTimeout);
}
else {
this.disposableServer.disposeNow();
}
// 对象销毁
this.disposableServer = null;
}
}
}
2、管理类
Netty组件中抽象管理类,以安全的方式构建Http服务;
public abstract class HttpServer {
public static HttpServer create() {
return HttpServerBind.INSTANCE;
}
public final DisposableServer bindNow() {
return bindNow(Duration.ofSeconds(45));
}
public final HttpServer handle(BiFunction<? super HttpServerRequest, ? super
HttpServerResponse, ? extends Publisher<Void>> handler) {
return new HttpServerHandle(this, handler);
}
}
六、参考源码
编程文档:
https://gitee.com/cicadasmile/butte-java-note
应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent
Gateway集成Netty服务的更多相关文章
- asp.net中关于Microsoft 信息完整性、隐私性等集成信息安全服务服务 integrated security=SSPI
string strConn=@"server=(local)\SQLExpress;database=AdventureWorks;integrated security=SSPI&quo ...
- Redola.Rpc 集成 Consul 服务发现
Redola.Rpc 解决了什么问题? Redola.Rpc 是一个使用 C# 开发的 RPC 框架,代码开源在 GitHub 上.目前版本仅支持 .NET Framework 4.6 以上版本,未来 ...
- idea/eclipse下Maven工程集成web服务(tomcat、jetty)
idea/eclipse下Maven工程集成web服务 转载请注明出处:http://www.cnblogs.com/funnyzpc/p/8093554.html 应用服务器最常用的一般有这哥仨: ...
- 【Netty源码分析】Netty服务端bind端口过程
这一篇博客我们介绍一下Netty服务端绑定端口的过程,我们通过跟踪代码一直到NIO原生绑定端口的操作. 绑定端口操作 ChannelFuture future = serverBootstrap.bi ...
- Netty 服务端启动过程
在 Netty 中创建 1 个 NioServerSocketChannel 在指定的端口监听客户端连接,这个过程主要有以下 个步骤: 创建 NioServerSocketChannel 初始化并注 ...
- Http 调用netty 服务,服务调用客户端,伪同步响应.ProtoBuf 解决粘包,半包问题.
实际情况是: 公司需要开发一个接口给新产品使用,需求如下 1.有一款硬件设备,客户用usb接上电脑就可以,但是此设备功能比较单一,所以开发一个服务器程序,辅助此设备业务功能 2.解决方案,使用Sock ...
- 7.4 服务远程暴露 - 创建Exporter与启动netty服务端
为了安全:服务启动的ip全部使用10.10.10.10 远程服务的暴露总体步骤: 将ref封装为invoker 将invoker转换为exporter 启动netty 注册服务到zookeeper 订 ...
- Netty 服务端创建
参考:http://blog.csdn.net/suifeng3051/article/details/28861883?utm_source=tuicool&utm_medium=refer ...
- 如何通过 AAR 形式集成 leakcanary-android 服务
如何通过 AAR 形式集成 leakcanary-android 服务 如何通过在线引用的方式拿到所有相关的依赖项文件? #1.禁用 Gradle 离线模式 #2.按照文档要求添加项目依赖 #3.Sy ...
- 2、Dubbo源码解析--服务发布原理(Netty服务暴露)
一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...
随机推荐
- 【每日一题】【map存值】2022年2月25日-NC112 进制转换
描述给定一个十进制数 M ,以及需要转换的进制数 N .将十进制数 M 转化为 N 进制数. 当 N 大于 10 以后, 应在结果中使用大写字母表示大于 10 的一位,如 'A' 表示此位为 10 , ...
- 现代 CSS 之高阶图片渐隐消失术
在过往,我们想要实现一个图片的渐隐消失.最常见的莫过于整体透明度的变化,像是这样: <div class="img"></div> div { width: ...
- utf-8与utf8mb4与base64和md5
utf-8与utf8mb4的区别 utf8--->utf-8,mysql字节的,两个字节表示一个字符--->生僻字,表示存不了 utf8mb4-->utf-8,最多4个字节表示一个字 ...
- Qt栅格布局、ScrollArea和用户选择界面
用户选择界面 就我们在实际开发的时候可能需要面对这样一个界面 做个demo试试看 其实我们可以分解一下这个界面 就是除了控制相关的内容,最主要的就是这个界面之上,有一个个动态的输入的控件,上面都是学生 ...
- GO语言基础 为什么我要学习Golang以及GO语言入门普及
作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.这系列文章入门部分将参考 ...
- 二阶段目标检测网络-FPN 详解
论文背景 引言(Introduction) 特征金字塔网络 FPN FPN网络建立 Anchor锚框生成规则 实验 代码解读 参考资料 本篇文章是论文阅读笔记和网络理解心得总结而来,部分资料和图参考论 ...
- cs231n__5.1/5.2 CNN
CS231n note 5.1 CNN_history now: 略 5.2 CNN 上节课我们谈到了全连接层的概念: 对于全连接层而言,我们要做的就是在这些向量上进行操作. 例如: 但是至于卷积层, ...
- 15、MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
转载自 一.报错信息: Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollback ...
- Springboot启动时加载
@Component public class SpringBootInitialization1 implements ServletContextListener { @Override publ ...
- CVE-2007-4556 s2-001
漏洞名称 S2-001 远程代码执行 利用条件 WebWork 2.1 (with altSyntax enabled), WebWork 2.2.0 - WebWork 2.2.5, Struts ...