Gateway集成Netty服务

简介: Netty是一个异步的,事件驱动的网络应用框架,用以快速开发高可靠、高性能的网络应用程序,提供网络传输能力的管理,支持常见的数据传输协议;
Gateway和Netty都有盲区的感觉;

一、Netty简介

Netty是一个异步的,事件驱动的网络应用框架,用以快速开发高可靠、高性能的网络应用程序。

1.png

传输服务:提供网络传输能力的管理;

协议支持:支持常见的数据传输协议;

核心模块:包括可扩展事件模型、通用的通信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、配置加载分析

2.png

  • 基于配置的属性,定制化管理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、控制类

3.png

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
相关文章
|
5月前
|
NoSQL Java Redis
小白版的springboot中集成mqtt服务(超级无敌详细),实现不了掐我头!!!
小白版的springboot中集成mqtt服务(超级无敌详细),实现不了掐我头!!!
|
1月前
|
Java Maven Windows
使用Java创建集成JACOB的HTTP服务
本文介绍了如何在Java中创建一个集成JACOB的HTTP服务,使Java应用能够调用Windows的COM组件。文章详细讲解了环境配置、动态加载JACOB DLL、创建HTTP服务器、实现IP白名单及处理HTTP请求的具体步骤,帮助读者实现Java应用与Windows系统的交互。作者拥有23年编程经验,文章来源于稀土掘金。著作权归作者所有,商业转载需授权。
使用Java创建集成JACOB的HTTP服务
|
8天前
|
存储 Java 开发工具
【三方服务集成】最新版 | 阿里云OSS对象存储服务使用教程(包含OSS工具类优化、自定义阿里云OSS服务starter)
阿里云OSS(Object Storage Service)是一种安全、可靠且成本低廉的云存储服务,支持海量数据存储。用户可通过网络轻松存储和访问各类文件,如文本、图片、音频和视频等。使用OSS后,项目中的文件上传业务无需在服务器本地磁盘存储文件,而是直接上传至OSS,由其管理和保障数据安全。此外,介绍了OSS服务的开通流程、Bucket创建、AccessKey配置及环境变量设置,并提供了Java SDK示例代码,帮助用户快速上手。最后,展示了如何通过自定义starter简化工具类集成,实现便捷的文件上传功能。
【三方服务集成】最新版 | 阿里云OSS对象存储服务使用教程(包含OSS工具类优化、自定义阿里云OSS服务starter)
|
14天前
Netty 与硬件设备交互,下行命令时(服务对设备),如何等待设备响应,再进行业务操作解决方案
Netty 与硬件设备交互,下行命令时(服务对设备),如何等待设备响应,再进行业务操作解决方案
|
2月前
|
存储 设计模式 缓存
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
该文章主要介绍了如何在OpenFeign中集成Ribbon以实现负载均衡,并详细分析了Ribbon中服务选择和服务过滤的核心实现过程。文章还涉及了Ribbon中负载均衡器(ILoadBalancer)和负载均衡策略(IRule)的初始化方式。
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
|
2月前
|
域名解析 网络协议 API
【API管理 APIM】APIM集成内部VNet时,常遇见的关于自定义DNS服务问题。
【API管理 APIM】APIM集成内部VNet时,常遇见的关于自定义DNS服务问题。
|
2月前
|
Java API 微服务
服务网关Gateway
该博客文章详细介绍了Spring Cloud Gateway的使用方法和概念。文章首先阐述了API网关在微服务架构中的重要性,解释了客户端直接与微服务通信可能带来的问题。接着,文章通过具体的示例代码,展示了如何在Spring Cloud Gateway中添加依赖、编写路由规则,并对路由规则中的基本概念如Route、Predicate和Filter进行了详细解释。最后,文章还提供了路由规则的测试方法。
服务网关Gateway
|
2月前
|
机器人 C# 人工智能
智能升级:WPF与人工智能的跨界合作——手把手教你集成聊天机器人,打造互动新体验与个性化服务
【8月更文挑战第31天】聊天机器人已成为现代应用的重要组成部分,提供即时响应、个性化服务及全天候支持。随着AI技术的发展,聊天机器人的功能日益强大,不仅能进行简单问答,还能实现复杂对话管理和情感分析。本文通过具体案例分析,展示了如何在WPF应用中集成聊天机器人,并通过示例代码详细说明其实现过程。使用Microsoft的Bot Framework可以轻松创建并配置聊天机器人,增强应用互动性和用户体验。首先,需在Bot Framework门户中创建机器人项目并编写逻辑。然后,在WPF应用中添加聊天界面,实现与机器人的交互。
47 0
|
3月前
|
Java Spring
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
69 3
|
2月前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
本节针对微服务中另一重要组件:网关 进行了实战性演练,网关作为分布式架构中的重要中间件,不仅承担着路由分发(重点关注Path规则配置),同时可根据自身负载均衡策略,对多个注册服务实例进行均衡调用。本节我们借助GateWay实现的网关只是技术实现的方案之一,后续大家可能会接触像:Zuul、Kong等,其实现细节或有差异,但整体目标是一致的。