";
23 | html += "update.....";
24 | resp.write(html);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code-netty-tomcat/src/main/java/com/hot/MyClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.hot;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * User: lanxinghua
8 | * Date: 2019/10/9 11:52
9 | * Desc: 实现热部署核心,通过自定义类加载器,创建新的对象,jvm进行加载
10 | */
11 | public class MyClassLoader extends ClassLoader {
12 | @Override
13 | public Class> findClass(String name) throws ClassNotFoundException {
14 | try {
15 | // 文件名称
16 | String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
17 | // 读取文件流
18 | InputStream is = this.getClass().getResourceAsStream("/com/catalina/servlet/" + fileName);
19 | // 读取字节
20 | byte[] b = new byte[is.available()];
21 | is.read(b);
22 | //数据给JVM识别Class对象
23 | return defineClass(name,b, 0, b.length);
24 | } catch (IOException e) {
25 | throw new ClassNotFoundException();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/code-netty-tomcat/src/main/resources/web.properties:
--------------------------------------------------------------------------------
1 | application.name=web
2 |
3 | servlet.test=testServlet
4 | servlet.test.className=com.catalina.servlet.TestServlet
5 | servlet.test.urlPattern=/test*
6 |
--------------------------------------------------------------------------------
/code-netty/README.md:
--------------------------------------------------------------------------------
1 | ## 手写简化版netty
2 | netty 源码比较复杂,考虑了许多可扩展、安全、性能等,netty 的核心就隐藏在这百花深处。我们就考虑核心的东西,实现简单版的netty,
3 | 更好理解netty核心原理。
4 |
5 | ## netty原理
6 |
7 | 
8 |
9 |
10 | ##### Reactor线程模型
11 | 
12 |
13 | 请求过程:
14 | > 1.客户端请求,reactor线程进行处理accept,专门负责轮询
15 | > 2.分发请求给对应的worker线程
16 | > 3.worker线程更加配置,继续分发或者处理请求
17 |
18 | MainReactorThread 与 SubReactorThread 线程,分别用于处理 ACCEPT 事件与其它 I/O 事件。
19 | MainReactorThread:
20 |
21 | > 在 main 方法中被调用 start 方法;
22 | 只注册了 ServerSocketChanel 的 ACCETP 事件;
23 | 知道全部 SubReactorThread 对象;
24 | 具有一个从 SubReactorThread 组中挑选出某一个 Thread 的方法;
25 | 具有启动 SubReactorThread 的方法;
26 | 将 channnel 视为 ServerSocketChannel;
27 | 调用 ServerSocketChannel.accept() 方法取得一个客户端的 SocketChannel;
28 | 把 SocketCahnnel 注册到 I/O 线程,关注 READ 事件。
29 |
30 | SubReactorThread:
31 |
32 | > 在 MainReactorThread 方法中被调用 start 方法;
33 | 只注册了 SocketChannel 的 READ 事件;
34 | 知道更多的 workThread,用于业务操作;
35 | 具有挑选 workThread 的方法;
36 | 从 channel 中读取数据;
37 | 把业务操作提交到 workThread;
38 | 写入响应数据;
39 |
40 |
41 |
--------------------------------------------------------------------------------
/code-netty/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/img/1.jpg
--------------------------------------------------------------------------------
/code-netty/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/img/2.jpg
--------------------------------------------------------------------------------
/code-netty/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | sourcecode
7 | com.demo
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | code-netty
13 |
14 |
15 |
16 | io.netty
17 | netty-all
18 | 4.1.31.Final
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/ClientStart.java:
--------------------------------------------------------------------------------
1 | package com.demo;
2 |
3 | import com.demo.bootstrap.ServerBootstrap;
4 | import com.demo.channel.NioSelectorRunnablePool;
5 |
6 | import java.net.InetSocketAddress;
7 | import java.util.concurrent.Executors;
8 |
9 | /**
10 | * User: lanxinghua
11 | * Date: 2019/10/17 09:48
12 | * Desc:
13 | */
14 | public class ClientStart {
15 | public static void main(String[] args) {
16 | // 初始化线程
17 | NioSelectorRunnablePool pool = new NioSelectorRunnablePool(Executors.newCachedThreadPool());
18 | // 配置
19 | ServerBootstrap bootstrap = new ServerBootstrap(pool);
20 | // 绑定端口
21 | bootstrap.connect("localhost", 8888);
22 | System.out.println("client start......");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/ServerStart.java:
--------------------------------------------------------------------------------
1 | package com.demo;
2 |
3 | import com.demo.bootstrap.ServerBootstrap;
4 | import com.demo.channel.NioSelectorRunnablePool;
5 |
6 | import java.net.InetSocketAddress;
7 | import java.util.concurrent.Executors;
8 |
9 | /**
10 | * User: lanxinghua
11 | * Date: 2019/10/17 09:48
12 | * Desc:
13 | */
14 | public class ServerStart {
15 | public static void main(String[] args) {
16 | // 初始化线程
17 | NioSelectorRunnablePool pool = new NioSelectorRunnablePool(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
18 | // 配置
19 | ServerBootstrap bootstrap = new ServerBootstrap(pool);
20 | // 绑定端口
21 | bootstrap.bind(new InetSocketAddress(8888));
22 | System.out.println("server start......");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/channel/IBoss.java:
--------------------------------------------------------------------------------
1 | package com.demo.channel;
2 |
3 | import java.nio.channels.ServerSocketChannel;
4 |
5 | /**
6 | * User: lanxinghua
7 | * Date: 2019/10/15 09:34
8 | * Desc:
9 | */
10 | public interface IBoss {
11 | /**
12 | * 加入一个新的serversockets
13 | * @param serverSocketChannel
14 | */
15 | public void registerAcceptChannelTask(ServerSocketChannel serverSocketChannel);
16 | }
17 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/channel/IWorker.java:
--------------------------------------------------------------------------------
1 | package com.demo.channel;
2 |
3 | import java.nio.channels.SocketChannel;
4 |
5 | /**
6 | * User: lanxinghua
7 | * Date: 2019/10/15 09:36
8 | * Desc:
9 | */
10 | public interface IWorker {
11 | /**
12 | * 加入新的客户端会话
13 | * @param socketChannel
14 | */
15 | public void registerNewChannelTask(SocketChannel socketChannel);
16 | }
17 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/channel/NioSelectorRunnablePool.java:
--------------------------------------------------------------------------------
1 | package com.demo.channel;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.concurrent.Executor;
7 | import java.util.concurrent.atomic.AtomicInteger;
8 |
9 | /**
10 | * User: lanxinghua
11 | * Date: 2019/10/15 09:41
12 | * Desc: selector线程管理者
13 | */
14 | public class NioSelectorRunnablePool {
15 | // boss线程组
16 | private final AtomicInteger bossIndex = new AtomicInteger();
17 | private List
bosses = new ArrayList();
18 |
19 | // worker线程组
20 | private final AtomicInteger workerIndex = new AtomicInteger();
21 | private List workers = new ArrayList();
22 |
23 | public NioSelectorRunnablePool(Executor worker) {
24 | initWorker(worker, Runtime.getRuntime().availableProcessors() * 2);
25 | }
26 |
27 | // 初始化
28 | public NioSelectorRunnablePool(Executor boss, Executor worker){
29 | initBoss(boss, 1);
30 | initWorker(worker, Runtime.getRuntime().availableProcessors() * 2);
31 | }
32 |
33 | private void initBoss(Executor boss, int count){
34 | for (int i = 0; i < count; i++) {
35 | bosses.add(new NioServerBoss(boss, "boss thread" + (i + 1), this));
36 | }
37 | }
38 |
39 | private void initWorker(Executor worker, int count){
40 | for (int i = 0; i < count; i++) {
41 | workers.add(new NioServerWorker(worker, "worker thread" + (i + 1), this));
42 | }
43 | }
44 |
45 | public IWorker nextWorker(){
46 | return workers.get(Math.abs(workerIndex.getAndIncrement() % workers.size()));
47 | }
48 |
49 | public IBoss nextBoss(){
50 | return bosses.get(Math.abs(bossIndex.getAndIncrement() % bosses.size()));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/code-netty/src/main/java/com/demo/channel/NioServerBoss.java:
--------------------------------------------------------------------------------
1 | package com.demo.channel;
2 |
3 | import java.nio.channels.SelectionKey;
4 | import java.nio.channels.Selector;
5 | import java.nio.channels.ServerSocketChannel;
6 | import java.nio.channels.SocketChannel;
7 | import java.util.Iterator;
8 | import java.util.Set;
9 | import java.util.concurrent.Executor;
10 |
11 | /**
12 | * User: lanxinghua
13 | * Date: 2019/10/17 09:38
14 | * Desc:
15 | */
16 | public class NioServerBoss extends AbstractNioSelector implements IBoss {
17 |
18 | public NioServerBoss(Executor executor, String threadName, NioSelectorRunnablePool selectorRunnablePool) {
19 | super(executor, threadName, selectorRunnablePool);
20 | }
21 |
22 | protected int select(Selector selector) throws Exception{
23 | return selector.select();
24 | }
25 |
26 | // selector业务处理
27 | protected void process(Selector selector) throws Exception{
28 | Set selectionKeys = selector.selectedKeys();
29 | if (selectionKeys.isEmpty()){
30 | return;
31 | }
32 | Iterator iterator = selectionKeys.iterator();
33 | while (iterator.hasNext()){
34 | SelectionKey key = iterator.next();
35 | iterator.remove();
36 | ServerSocketChannel server = (ServerSocketChannel) key.channel();
37 | // 新客户端
38 | SocketChannel channel = server.accept();
39 | // 设为非阻塞
40 | channel.configureBlocking(false);
41 | // 获取worker线程
42 | IWorker worker = selectorRunnablePool.nextWorker();
43 | // 注册新客户端接入任务
44 | worker.registerNewChannelTask(channel);
45 | System.out.println("新客户端连接......");
46 | }
47 | }
48 |
49 | public void registerAcceptChannelTask(final ServerSocketChannel serverSocketChannel) {
50 | final Selector selector = this.selector;
51 | addTask(new Runnable() {
52 | public void run() {
53 | try {
54 | serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
55 | }catch (Exception e){
56 | e.printStackTrace();
57 | }
58 | }
59 | });
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/code-netty/src/main/resources/config.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-netty/src/main/resources/config.properties
--------------------------------------------------------------------------------
/code-proxy/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-proxy/img/1.png
--------------------------------------------------------------------------------
/code-proxy/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-proxy/img/2.jpg
--------------------------------------------------------------------------------
/code-proxy/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | sourcecode
7 | com.demo
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | com.demo
13 | code-proxy
14 |
15 |
16 |
17 | org.apache.maven.plugins
18 | maven-compiler-plugin
19 |
20 | 1.6
21 | 1.6
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | cglib
30 | cglib
31 | 3.2.5
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/IUserService.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | /**
4 | * @Author: cxx
5 | * @Date: 2019/10/1 22:40
6 | */
7 | public interface IUserService {
8 | public void delete(String id);
9 | }
10 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/UserService.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | /**
4 | * @Author: cxx
5 | * @Date: 2019/10/1 22:40
6 | */
7 | public class UserService implements IUserService {
8 | public void delete(String id) {
9 | System.out.println("删除用户 id:" + id);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/cglib/CglibTest.java:
--------------------------------------------------------------------------------
1 | package com.cglib;
2 |
3 | import com.UserService;
4 | import net.sf.cglib.core.DebuggingClassWriter;
5 | import net.sf.cglib.proxy.Enhancer;
6 | import net.sf.cglib.proxy.MethodInterceptor;
7 | import net.sf.cglib.proxy.MethodProxy;
8 |
9 | import java.lang.reflect.Method;
10 |
11 | /**
12 | * @Author: cxx
13 | * @Date: 2019/10/1 22:49
14 | */
15 | public class CglibTest {
16 | public static void main(String[] args) {
17 | //代理类class文件存入本地磁盘
18 | System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "F:\\code");
19 | Enhancer enhancer = new Enhancer();
20 | enhancer.setSuperclass(UserService.class);
21 | enhancer.setCallback(new MethodInterceptor() {
22 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
23 | System.out.println("before");
24 | methodProxy.invokeSuper(o, objects);
25 | System.out.println("after");
26 | return null;
27 | }
28 | });
29 | UserService userServiceProxy = (UserService) enhancer.create();
30 | userServiceProxy.delete("100");
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/jdk/JdkTest.java:
--------------------------------------------------------------------------------
1 | package com.jdk;
2 |
3 | import com.IUserService;
4 | import com.UserService;
5 |
6 | import java.lang.reflect.InvocationHandler;
7 | import java.lang.reflect.Method;
8 | import java.lang.reflect.Proxy;
9 |
10 | /**
11 | * @Author: cxx
12 | * @Date: 2019/10/1 22:41
13 | */
14 | public class JdkTest {
15 | public static void main(String[] args) {
16 | IUserService userServiceProxy = (IUserService) Proxy.newProxyInstance(
17 | UserService.class.getClassLoader(),
18 | UserService.class.getInterfaces(),
19 | new InvocationHandler() {
20 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21 | System.out.println("before");
22 | method.invoke(new UserService(), args);
23 | System.out.println("after");
24 | return null;
25 | }
26 | }
27 | );
28 | userServiceProxy.delete("100");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/my/$ProxyMy.java:
--------------------------------------------------------------------------------
1 | package com.my;
2 |
3 | import com.IUserService;
4 |
5 | import java.lang.reflect.Method;
6 |
7 | /**
8 | * @Author: cxx
9 | * @Date: 2019/10/2 11:29
10 | * 动态生成代理类:如下
11 | */
12 | public class $ProxyMy implements IUserService {
13 | private MyInvocationHandler invocationHandler;
14 |
15 | public $ProxyMy(MyInvocationHandler invocationHandler) {
16 | this.invocationHandler = invocationHandler;
17 | }
18 |
19 | public void delete(String id) {
20 | try {
21 | Method m = IUserService.class.getMethod("delete", String.class);
22 | invocationHandler.invoke(this, m, new Object[]{id});
23 | } catch (Throwable throwable) {
24 | throwable.printStackTrace();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/my/MyClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.my;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 |
7 | /**
8 | * @Author: cxx
9 | * @Date: 2019/10/2 14:24
10 | */
11 | public class MyClassLoader extends ClassLoader{
12 | private String baseDir;
13 |
14 | public MyClassLoader() {
15 | this.baseDir = this.getClass().getResource("").getFile();
16 | }
17 |
18 | @Override
19 | protected Class> findClass(String name) throws ClassNotFoundException {
20 | String className = this.getClass().getPackage().getName() + "." + name;
21 | if (baseDir != null && baseDir != ""){
22 | File f = new File(baseDir + "/" + name +".class");
23 | ByteArrayOutputStream out = null;
24 | FileInputStream fis = null;
25 | if (f.exists()){
26 | try {
27 | fis = new FileInputStream(f);
28 | out = new ByteArrayOutputStream();
29 | byte[] b = new byte[1024];
30 | int len;
31 | while ((len = fis.read(b)) != -1){
32 | out.write(b, 0, len);
33 | }
34 | return defineClass(className, out.toByteArray(), 0, out.size());
35 | }catch (Exception e){
36 | e.printStackTrace();
37 | }finally {
38 | if (fis != null){
39 | try {
40 | fis.close();
41 | }catch (Exception e){
42 | e.printStackTrace();
43 | }
44 | }
45 | if (out != null){
46 | try {
47 | out.close();
48 | }catch (Exception e){
49 | e.printStackTrace();
50 | }
51 | }
52 | // 查看.class文件
53 | // f.delete();
54 | }
55 | }
56 | }
57 | return null;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/my/MyInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package com.my;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | /**
6 | * @Author: cxx
7 | * @Date: 2019/10/2 11:11
8 | */
9 | public interface MyInvocationHandler {
10 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
11 | }
12 |
--------------------------------------------------------------------------------
/code-proxy/src/main/java/com/my/MyTest.java:
--------------------------------------------------------------------------------
1 | package com.my;
2 |
3 | import com.IUserService;
4 | import com.UserService;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * @Author: cxx
10 | * @Date: 2019/10/2 11:13
11 | */
12 | public class MyTest {
13 | public static void main(String[] args) {
14 | IUserService userServiceProxy = (IUserService) MyProxy.newProxyInstance(
15 | new MyClassLoader(),
16 | UserService.class.getInterfaces(),
17 | new MyInvocationHandler() {
18 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
19 | System.out.println("before");
20 | method.invoke(new UserService(), args);
21 | System.out.println("after");
22 | return null;
23 | }
24 | }
25 | );
26 | userServiceProxy.delete("100");
27 |
28 | // 其实就是生成一个代理类
29 | IUserService proxyMy = new $ProxyMy(new MyInvocationHandler() {
30 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
31 | System.out.println("before");
32 | method.invoke(new UserService(), args);
33 | System.out.println("after");
34 | return null;
35 | }
36 | });
37 | //proxyMy.delete("100");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/code-redis/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/1.jpg
--------------------------------------------------------------------------------
/code-redis/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/2.png
--------------------------------------------------------------------------------
/code-redis/img/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/3.png
--------------------------------------------------------------------------------
/code-redis/img/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/4.png
--------------------------------------------------------------------------------
/code-redis/img/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/5.png
--------------------------------------------------------------------------------
/code-redis/img/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/6.png
--------------------------------------------------------------------------------
/code-redis/img/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/7.png
--------------------------------------------------------------------------------
/code-redis/img/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/8.png
--------------------------------------------------------------------------------
/code-redis/img/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenxingxing6/sourcecode/e8b641be7f94641afb26e2b31d1bbd8787a04ac6/code-redis/img/9.png
--------------------------------------------------------------------------------
/code-redis/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | sourcecode
7 | com.demo
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | com.demo
13 | code-redis
14 |
15 |
16 |
17 | org.apache.maven.plugins
18 | maven-compiler-plugin
19 |
20 | 1.8
21 | 1.8
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | redis.clients
30 | jedis
31 | 2.9.0
32 |
33 |
34 | junit
35 | junit
36 | 4.12
37 | test
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/code-redis/src/main/java/com/demo/JedisTest.java:
--------------------------------------------------------------------------------
1 | package com.demo;
2 |
3 | import redis.clients.jedis.Jedis;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * @Author: cxx
9 | * @Date: 2019/11/3 23:28
10 | */
11 | public class JedisTest {
12 | public static void main(String[] args) throws Exception{
13 | Jedis jedis=new Jedis("localhost", 6379);
14 | String result = jedis.ping();
15 | System.out.println(result);
16 |
17 | TimeUnit.SECONDS.sleep(2);
18 | //关闭jedis
19 | jedis.close();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code-redis/src/main/java/com/demo/MyRedisService.java:
--------------------------------------------------------------------------------
1 | package com.demo;
2 |
3 | import com.demo.command.ICommand;
4 | import com.demo.data.PermanentData;
5 | import com.demo.procotol.MyDecode;
6 |
7 | import java.io.InputStream;
8 | import java.io.OutputStream;
9 | import java.net.ServerSocket;
10 | import java.net.Socket;
11 | import java.util.concurrent.ExecutorService;
12 | import java.util.concurrent.Executors;
13 | import java.util.concurrent.TimeUnit;
14 |
15 | /**
16 | * @Author: cxx
17 | * @Date: 2019/11/3 19:48
18 | */
19 | public class MyRedisService {
20 |
21 | public static void main(String[] args) {
22 | new MyRedisService().start(6379);
23 | }
24 |
25 | public void start(int port){
26 | // 1.加载持久化数据
27 | loadData();
28 | ExecutorService executor = Executors.newFixedThreadPool(20000);
29 | ServerSocket serverSocket = null;
30 | try {
31 | // 循环接受客户端连接
32 | serverSocket = new ServerSocket(port);
33 | System.out.println("等待客户端连接....");
34 | while (true){
35 | final Socket socket = serverSocket.accept();
36 | executor.execute(() -> {
37 | try {
38 | // 持续提供业务服务
39 | while (true){
40 | InputStream is = socket.getInputStream();
41 | OutputStream os = socket.getOutputStream();
42 | // 解析命令
43 | ICommand command = new MyDecode(is, os).getCommand();
44 | if (command != null){
45 | command.run(os);
46 | }
47 | TimeUnit.MILLISECONDS.sleep(10);
48 | }
49 | }catch (Exception e){
50 | try {
51 | socket.close();
52 | }catch (Exception e1){
53 | }
54 | }
55 | });
56 | }
57 | }catch (Exception e){
58 | try {
59 | serverSocket.close();
60 | }catch (Exception e1){
61 |
62 | }
63 | }
64 | }
65 |
66 | public void loadData(){
67 | PermanentData.getInstance().readFromListProfile();
68 | PermanentData.getInstance().readFromMapProfile();
69 | System.out.println("数据加载完成....");
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/code-redis/src/main/java/com/demo/command/EXITCommand.java:
--------------------------------------------------------------------------------
1 | package com.demo.command;
2 |
3 | import java.io.OutputStream;
4 | import java.util.List;
5 |
6 | /**
7 | * @Author: cxx
8 | * @Date: 2019/11/3 19:51
9 | */
10 | public class EXITCommand implements ICommand {
11 | public List