架构师养成记--19.netty
一、Netty初步
为什么选择Netty?
和NIO比较,要实现一个通信要简单得很多,性能很好。分布式消息中间件、storm、Dubble都是使用Netty作为底层通信。
Netty5.0要求jdk1.6以上。
http://netty.io
二、编码步骤
创建两个Nio线程组,一个事件处理,一个网络读写通信
创建一个ServerBootStrap,配置Netty参数;
创建实际处理的ChannelInitializer,进行初始化的准备工作,比如设置接收传出的字符集,格式,已经实际处理数据接口
绑定端口执行同步阻塞方法等待服务器端启动。
并发编程网 http://ifeve.com/netty5-user-guide
三、代码
服务端
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; /**
* Created by sgm on 2017/1/28.
*/
public class Server {
public static void main(String []args) throws InterruptedException {
/**
* EventLoopGroup 事件组,不同的事件组处理不同的协议,这里使用NioEventLoopGroup来处理Tcp协议
* 第一个事件循环组用来接收客户端信息,通常被称作boss,boos接收到信息后注册到worker上
* 第二个事件循环组做实际的业务处理
*/
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup(); /**
* 引导,对server进行一系列的配置
*/
ServerBootstrap b = new ServerBootstrap();
//将boss和worker关联起来
b.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)//使用的通道类型
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new ServerHandler());
}
})//添加serverHandler,绑定具体的事件处理器
/**
* 当客户端向客户端发送请求会带一个信号,服务器端返回一个信号并且将客户端的链接信息加入队列A中,
* 服务器再收到一个客户端的信号并且将客户端的信息从队列A移动到队列B中;
* 队列A和队列B的长度之和就是BACKLOG,如果大于了BACKLOG,tcp内核就会拒绝链接,BACKLOG只会影响到没有被accept取出的链接
*/
.option(ChannelOption.SO_BACKLOG,128)
.option(ChannelOption.SO_KEEPALIVE,true);//保持连接
ChannelFuture cf = b.bind(9876).sync();//绑定端口进行监听,异步的监听 cf.channel().closeFuture().sync();//阻塞
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully(); }
}
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; /**
* Created by Administrator on 2017/1/28.
*/
public class ServerHandler extends ChannelHandlerAdapter{ @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Server: " + request);
//写给客户端
String response = "我是反馈的信息";
ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));
}finally {
ReferenceCountUtil.release(msg);//有上一句话,即ctx.writeAndFlush(),这里可以不关闭
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; public class Client { public static void main(String[] args) throws Exception { EventLoopGroup workgroup = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(workgroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ClientHandler());
}
}); ChannelFuture cf1 = b.connect("127.0.0.1", 9876).sync(); //buf
cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes())); cf1.channel().closeFuture().sync();
workgroup.shutdownGracefully(); }
}
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Client: " + request); } finally {
ReferenceCountUtil.release(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
架构师养成记--19.netty的更多相关文章
- 架构师养成记--21.netty编码解码
背景 作为网络传输框架,免不了哟啊传输对象,对象在传输之前就要序列化,这个序列化的过程就是编码过程.接收到编码后的数据就需要解码,还原传输的数据. 代码 工厂类 import io.netty.han ...
- 架构师养成记--20.netty的tcp拆包粘包问题
问题描述 比如要发ABC DEFG HIJK 这一串数据,其中ABC是一个包,DEFG是一个包,HIJK是一个包.由于TCP是基于流发送的,所以有可能出现ABCD EFGH 这种情况,那么ABC和D就 ...
- 架构师养成记--22.客户端与服务器端保持连接的解决方案,netty的ReadTimeoutHandler
概述 保持客户端与服务器端连接的方案常用的有3种 1.长连接,也就是客户端与服务器端一直保持连接,适用于客户端比较少的情况. 2.定时段连接,比如在某一天的凌晨建立连接,适用于对实时性要求不高的情况. ...
- 架构师养成记--35.redis集群搭建
前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...
- 架构师养成记--15.Disruptor并发框架
一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...
- 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock
ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...
- 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch
java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...
- 架构师养成记--11.Executor概述
常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...
- 架构师养成记--10.master-worker模式
master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...
随机推荐
- IDEA00 IDEA知识点汇总
一.从头搭建IDEA开发环境 https://mp.weixin.qq.com/s/6jXHzkU8JfubhDsQJbwl8Q 1 下载最新版IDEA 1.1 官网下载安装 1.2 专业版激活 2 ...
- C语言中的undefined behavior
参考: http://www.cnblogs.com/aoaoblogs/archive/2010/08/31/1813982.html
- lua简单包装
#ifndef _LUA_WRAPPER_ #define _LUA_WRAPPER_ extern "C" { #include "lua.h" #inclu ...
- Cook-Torrence Illumination Model 的一些数学说明
Cook-Torrence 光照模型如下: 这个Io就是计算后最终的光强,主要是用来计算镜面反射光,漫反射和环境光的计算和Phong模型一致. F:Fresnel反射系数.主要用来说明反射光强度占入射 ...
- ResourceUtils读取properties文件
注意: properties文件要放在classPath下面,也就是与src下. path.properties(在properties文件中\代表着没有完,下行同本行是一个内容) perfectMa ...
- 在PowerDesigner中设计物理模型1——表和主外键(转)
出处:http://www.cnblogs.com/studyzy/archive/2009/12/15/1624899.html 在PD中建立物理模型由以下几种办法: 直接新建物理模型. 设计好概念 ...
- 利用BeanUtils.copyProperties 克隆出新对象,避免对象重复问题
1.经常用jQuery获取标签里面值val(),或者html(),text()等等,有次想把获取标签的全部html元素包括自己也用来操作,查询了半天发现$("#lefttr1"). ...
- Redis Quick Start [熟练版]
一.下载解压 wget http://download.redis.io/redis-stable.tar.gztar xvzf redis-stable.tar.gzcd redis-stable ...
- dojo表格操作的简单示例(建立表格)
代码示例: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...
- 汉诺塔问题的算法分析与实现(Java)
汉诺塔问题是源于印度一个古老传说的益智玩具.要求将圆盘从A柱移动到C柱规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 可以先通过3个盘子的hanoi游戏得出其算法步骤如下: if ...