pom文件
<dependency> <groupId>io.netty</groupId> <artifactId>netty-example</artifactId> <version>4.1.8.Final</version> <exclusions> <exclusion> <artifactId>netty-tcnative</artifactId> <groupId>io.netty</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative</artifactId> <version>1.1.33.Fork26</version> <classifier>linux-x86_64-fedora</classifier> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> </dependency>
package com.snailteam.netty.memcached; import java.util.concurrent.atomic.AtomicInteger; import io.netty.handler.codec.memcache.binary.FullBinaryMemcacheResponse; import io.netty.util.CharsetUtil; import junit.framework.Assert; public class App { public static void main(String[] args) throws InterruptedException { NioSession session = new NioSession("127.0.0.1", 11211); AtomicInteger counter = new AtomicInteger(0); while (true) { FullBinaryMemcacheResponse res = null; String keyString = "user_id:" + counter.getAndIncrement(); session.send(keyString, keyString); res = session.resp(); session.get(keyString); res = session.resp(); Assert.assertEquals(keyString, res.content().toString(CharsetUtil.UTF_8)); if (counter.get() > 10000) break; } session.close(); } }
package com.snailteam.netty.memcached; import java.net.InetSocketAddress; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.memcache.binary.BinaryMemcacheClientCodec; import io.netty.handler.codec.memcache.binary.BinaryMemcacheObjectAggregator; import io.netty.handler.codec.memcache.binary.BinaryMemcacheOpcodes; import io.netty.handler.codec.memcache.binary.BinaryMemcacheRequest; import io.netty.handler.codec.memcache.binary.DefaultBinaryMemcacheRequest; import io.netty.handler.codec.memcache.binary.DefaultFullBinaryMemcacheRequest; import io.netty.handler.codec.memcache.binary.FullBinaryMemcacheResponse; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.util.CharsetUtil; public class NioSession { private MemcachedProtocol protocol; private Channel channel; private Bootstrap boot; public NioSession(String host, int port) throws InterruptedException { protocol = new MemcachedProtocol(); boot = new Bootstrap().group(new NioEventLoopGroup()).channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true).remoteAddress(new InetSocketAddress(host, port)) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG), new BinaryMemcacheClientCodec(), new BinaryMemcacheObjectAggregator(Integer.MAX_VALUE), protocol); } }); channel = boot.connect().sync().channel(); } void send(String keyString, String value) throws InterruptedException { ByteBuf key = Unpooled.wrappedBuffer(keyString.getBytes(CharsetUtil.UTF_8)); ByteBuf content = Unpooled.wrappedBuffer(value.getBytes(CharsetUtil.UTF_8)); ByteBuf extras = channel.alloc().buffer(8); extras.writeZero(8); BinaryMemcacheRequest req = new DefaultFullBinaryMemcacheRequest(key, extras, content); req.setOpcode(BinaryMemcacheOpcodes.SET); channel.writeAndFlush(req); } public FullBinaryMemcacheResponse resp() throws InterruptedException { return protocol.resp(); } public void get(String keyString) throws InterruptedException { ByteBuf key = Unpooled.wrappedBuffer(keyString.getBytes(CharsetUtil.UTF_8)); BinaryMemcacheRequest req = new DefaultBinaryMemcacheRequest(key); req.setOpcode(BinaryMemcacheOpcodes.GET); channel.writeAndFlush(req); } public void close() { if (channel != null && channel.isActive()) { channel.close(); } if( protocol != null ) { protocol.wakeUpAll() ; protocol = null ; } channel = null; if (boot != null && boot.config() != null) { boot.config().group().shutdownGracefully(); } boot = null; } }
package com.snailteam.netty.memcached; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedTransferQueue; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.memcache.binary.FullBinaryMemcacheResponse; public class MemcachedProtocol extends ChannelInboundHandlerAdapter { private BlockingQueue<FullBinaryMemcacheResponse> queue = new LinkedTransferQueue<FullBinaryMemcacheResponse>(); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { queue.add((FullBinaryMemcacheResponse) msg); } public FullBinaryMemcacheResponse resp() throws InterruptedException { return queue.take(); } public void wakeUpAll() { while ( queue.poll() != null ) { } this.queue = null ; } }
参考 https://github.com/fl061157/surf-memcached