资讯专栏INFORMATION COLUMN

NettyServer与SpringBoot集成

U2FsdGVkX1x / 1171人阅读

摘要:的非工程的会根据类路径是否有来判断是否是项目,也可以自己强制指定。添加依赖如果是多模块的项目,由于子模块已经有了,所以只能把的放到子模块的的文件上。

SpringBoot的非web工程

SpringBoot的AutoConfiguration会根据类路径是否有servlet来判断是否是web项目,也可以自己强制指定。

@SpringBootApplication
public class RpcServerApplication {

    public static void main(String[] args){
        SpringApplication app = new SpringApplication(RpcServerApplication.class);
        app.setWebEnvironment(false);
        app.run(args);
    }
}
添加依赖

如果是多模块的项目,由于子模块已经有parent了,所以只能把spring boot的parent放到子模块的parent的pom文件上。


    org.springframework.boot
    spring-boot-starter-parent
    1.3.3.RELEASE
     
  

    UTF-8
  

Spring IOC

        
        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
在bean初始化之后启动
@Component
//实现ApplicationContextAware以获得ApplicationContext中的所有bean
public class NettyServer implements ApplicationContextAware {

    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);

    private Channel channel;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;

    private Map exportServiceMap = new HashMap();

    @Value("${rpcServer.host:127.0.0.1}")
    String host;

    @Value("${rpcServer.ioThreadNum:5}")
    int ioThreadNum;
    //内核为此套接口排队的最大连接个数,对于给定的监听套接口,内核要维护两个队列,未链接队列和已连接队列大小总和最大值

    @Value("${rpcServer.backlog:1024}")
    int backlog;

    @Value("${rpcServer.port:9090}")
    int port;

    /**
     * 启动
     * @throws InterruptedException
     */
    @PostConstruct
    public void start() throws InterruptedException {
        logger.info("begin to start rpc server");
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup(ioThreadNum);

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, backlog)
                //注意是childOption
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                //真实数据最大字节数为Integer.MAX_VALUE,解码时自动去掉前面四个字节
                                //io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(900) + length(176) exceeds writerIndex(1024): UnpooledUnsafeDirectByteBuf(ridx: 900, widx: 1024, cap: 1024)
                                .addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
                                .addLast("encoder", new LengthFieldPrepender(4, false))
                                .addLast(new RpcDecoder(RpcRequest.class))
                                .addLast(new RpcEncoder(RpcResponse.class))
                                .addLast(new ServerRpcHandler(exportServiceMap));
                    }
                });

        channel = serverBootstrap.bind(host,port).sync().channel();

        logger.info("NettyRPC server listening on port " + port + " and ready for connections...");
    }

    @PreDestroy
    public void stop() {
        logger.info("destroy server resources");
        if (null == channel) {
            logger.error("server channel is null");
        }
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        channel.closeFuture().syncUninterruptibly();
        bossGroup = null;
        workerGroup = null;
        channel = null;
    }

    /**
     * 利用此方法获取spring ioc接管的所有bean
     * @param ctx
     * @throws BeansException
     */
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        Map serviceMap = ctx.getBeansWithAnnotation(ServiceExporter.class); // 获取所有带有 ServiceExporter 注解的 Spring Bean
        logger.info("获取到所有的RPC服务:{}", serviceMap);
        if (serviceMap != null && serviceMap.size() > 0) {
            for (Object serviceBean : serviceMap.values()) {
                String interfaceName = serviceBean.getClass().getAnnotation(ServiceExporter.class)
                        .targetInterface()
                        .getName();
                logger.info("register service mapping:{}",interfaceName);
                exportServiceMap.put(interfaceName, serviceBean);
            }
        }
    }
}
工程netty-rpc

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65765.html

相关文章

  • Dubbo 源码分析11 网络通信篇NettyServer、HeaderExchangeServer

    摘要:线程组负责连接事件线程组负责事件代码调用父类的构造方法,主要初始化和代码根据中的与端口,创建。当服务端向写入响应结果时,首先编码器会按照协议编码成二进制流,供客户端解码。 NettyServer 1、private Map< String, Channel> channels:< ip:port, channel> 所...

    不知名网友 评论0 收藏0
  • 原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上)

    摘要:端引导类线程管理组线程管理组将设置到服务端引导类中指定通道类型为,一种异步模式,阻塞模式为设置让服务器监听某个端口已等待客户端连接。 原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上) - 一、大致介绍 1、Netty这个词,对于熟悉并发的童鞋一点都不陌生,它是一个异步事件驱动型的网络通信框架; 2、使用Netty不需要我们关注过多NIO的API操作,简简单单的使用即可...

    coordinate35 评论0 收藏0
  • SpringBootAngular2的集成

    摘要:背景以为启动的框架,以为前端页面的框架,最后需要将的代码运行在内置中。最终生成的包中也会包含这些内容。本地启动项目测试如果继续使用的启动方式函数运行,由于中并没有的代码,则不会正确看到页面。解决办法就是使用另一个插件,专门用于的命令。 背景 以springboot为tomcat启动的框架,以angular2为前端页面的框架,最后需要将angular2的代码运行在springboot内置...

    骞讳护 评论0 收藏0
  • 使用Protostuff序列化

    摘要:序调用,有多种序列化的方式,通用如,使用的方面的,比如默认的序列化,比如还有跨语言的,比如。所以也一直在寻找运行效率与开发效率兼得的序列化方式。偶尔在网上看到,觉得找到了一直在找的这种序列化方式。 序 rpc调用,有多种序列化的方式,通用如json,mongodb使用的bson;java方面的,比如Java默认的序列化,比如hessian;还有跨语言的,比如thrift、protoco...

    ephererid 评论0 收藏0
  • SpringBoot 1024行代码 - 集成Logback

    前言 SpringBoot是一个全家桶,可以方便的集成各种开发工具。日志框架是一个在线应用必需的,本文介绍了当前主流日志框架Logback与SpringBoot的集成方法 准备工作 完成SpringBoot 1024行代码 - Getting Started(一个简单的web应用) 具体步骤 1. 添加Logback的配置文件logback-springboot.xml 其中文件名需要为logba...

    dailybird 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<