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服务的更多相关文章

  1. asp.net中关于Microsoft 信息完整性、隐私性等集成信息安全服务服务 integrated security=SSPI

    string strConn=@"server=(local)\SQLExpress;database=AdventureWorks;integrated security=SSPI&quo ...

  2. Redola.Rpc 集成 Consul 服务发现

    Redola.Rpc 解决了什么问题? Redola.Rpc 是一个使用 C# 开发的 RPC 框架,代码开源在 GitHub 上.目前版本仅支持 .NET Framework 4.6 以上版本,未来 ...

  3. idea/eclipse下Maven工程集成web服务(tomcat、jetty)

     idea/eclipse下Maven工程集成web服务 转载请注明出处:http://www.cnblogs.com/funnyzpc/p/8093554.html 应用服务器最常用的一般有这哥仨: ...

  4. 【Netty源码分析】Netty服务端bind端口过程

    这一篇博客我们介绍一下Netty服务端绑定端口的过程,我们通过跟踪代码一直到NIO原生绑定端口的操作. 绑定端口操作 ChannelFuture future = serverBootstrap.bi ...

  5. Netty 服务端启动过程

    在 Netty 中创建 1 个 NioServerSocketChannel 在指定的端口监听客户端连接,这个过程主要有以下  个步骤: 创建 NioServerSocketChannel 初始化并注 ...

  6. Http 调用netty 服务,服务调用客户端,伪同步响应.ProtoBuf 解决粘包,半包问题.

    实际情况是: 公司需要开发一个接口给新产品使用,需求如下 1.有一款硬件设备,客户用usb接上电脑就可以,但是此设备功能比较单一,所以开发一个服务器程序,辅助此设备业务功能 2.解决方案,使用Sock ...

  7. 7.4 服务远程暴露 - 创建Exporter与启动netty服务端

    为了安全:服务启动的ip全部使用10.10.10.10 远程服务的暴露总体步骤: 将ref封装为invoker 将invoker转换为exporter 启动netty 注册服务到zookeeper 订 ...

  8. Netty 服务端创建

    参考:http://blog.csdn.net/suifeng3051/article/details/28861883?utm_source=tuicool&utm_medium=refer ...

  9. 如何通过 AAR 形式集成 leakcanary-android 服务

    如何通过 AAR 形式集成 leakcanary-android 服务 如何通过在线引用的方式拿到所有相关的依赖项文件? #1.禁用 Gradle 离线模式 #2.按照文档要求添加项目依赖 #3.Sy ...

  10. 2、Dubbo源码解析--服务发布原理(Netty服务暴露)

    一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...

随机推荐

  1. flutter系列之:如丝般顺滑的SliverAppBar

    目录 简介 SliverAppBar详解 SliverAppBar的使用 总结 简介 对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等.虽然我们可以用一个固定 ...

  2. Django聚合函数与分组查询

    目录 一:聚合查询 1.聚合函数作用 2.聚合函数查询关键字: 3.聚合函数 4.聚合函数使用 二:分组查询 1.分组查询 2.返回值 3.分组查询关键字 4.分组查询特点 5总结: 三:分组使用 1 ...

  3. Go语言使用场景 | go语言与其它开源语言比较 | Go WEB框架选型

    一.Go语言使用场景 1. 关于go语言 2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Griesemer和Ken Thompson两位牛人,决定创造一种新 ...

  4. vue elementui弹框内 富文本编辑器的使用,及踩坑

    最近vue项目中遇到弹框内使用富文本编辑器,遇到最大的问题是,在打开弹框后才能创建富文本编辑器,并且只能创建一次,多次点击弹框,报错: Error in v-on handler: "Err ...

  5. npm Error: Cannot find module 'are-we-there-yet'

    npm 损坏了,are-we-there-yet是npm所依赖的npmlog依赖的一个包,重新安装npm即可 踩坑,直接安装还是报错,不管执行哪个命令都是报下面这个错 网上百度了很多,有的说把node ...

  6. 红袖添香,绝代妖娆,Ruby语言基础入门教程之Ruby3基础语法,第一次亲密接触EP01

    书接上回,前一篇我们在全平台构建好了Ruby3的开发环境,现在,可以和Ruby3第一次亲密接触了. Ruby是一门在面向对象层面无所不用其极的解释型编程语言. 我们可以把编写Ruby代码看作是一场行为 ...

  7. 1、Java数据类型

    1.基本数据类型的变量: /** * 1.基本数据类型的变量: * * 1).整数类型:byte(1字节=8bit),short(2字节),int(4字节),long(8字节) * * 2).浮点数类 ...

  8. 大数据 - DWS层 业务实现

    统计主题 需求指标[ADS] 输出方式 计算来源 来源层级 访客[DWS] pv 可视化大屏 page_log 直接可求 dwd UV(DAU) 可视化大屏 需要用 page_log 过滤去重 dwm ...

  9. MRS芯片状态错误排查方向

    1. 如手里的 LINK 板子标注是 WCH-LINK,而不是 WCH-LINKE,那么与开发板连接线最好别超过 15CM 2. 芯片供电是否正常, VDDA 和 VDD 要正常供电 2.检查连线是否 ...

  10. Swagger2多包扫描

    package com.xf.config; import org.springframework.context.annotation.Bean; import org.springframewor ...