当前位置: 首页 > news >正文

手写rpc和redis

rpc框架搭建
consumer 消费者应用
provider 提供的服务
Provider-common 公共类模块
rpc 架构
service-Registration 服务发现
nacos nacos配置中心
load-balancing 负载均衡
redis-trench 手写redis实现和链接

package com.trench.protocol;import com.trench.enumUtil.RedisRepEnum;
import redis.clients.jedis.util.SafeEncoder;import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;public class Protocol {public static final  String DOLLAR="$";public static final String STAR="*";public static final String BLANK="\r\n";public static void  sendCommand(OutputStream outputStream, RedisRepEnum redisRepEnum,byte [] ... args){StringBuffer str=new StringBuffer();str.append(STAR).append(args.length-1).append(BLANK);str.append(DOLLAR).append(redisRepEnum.name().length()).append(BLANK);str.append(redisRepEnum).append(BLANK);Arrays.stream(args).forEach(arg->{str.append(DOLLAR).append(arg.length).append(BLANK);str.append(new String(arg)).append(BLANK);});try {outputStream.write(str.toString().getBytes(StandardCharsets.UTF_8));} catch (IOException e) {e.printStackTrace();}}public static final byte[] toByteArray(long value) {return SafeEncoder.encode(String.valueOf(value));}
}
package com.trench.api;import com.trench.connection.Connetion;
import com.trench.enumUtil.RedisRepEnum;
import com.trench.protocol.Protocol;
import com.trench.util.SerializeUtils;
import redis.clients.jedis.BuilderFactory;import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;public class Client {Connetion connetion;public Client(String host,Integer port){connetion=new Connetion(port,host);}public void set(final  String key, final String values){connetion.sendCommand( RedisRepEnum.SET,key.getBytes(StandardCharsets.UTF_8), SerializeUtils.serialize(values));}public Object get(final String key){connetion.sendCommand(RedisRepEnum.GET,key.getBytes(StandardCharsets.UTF_8));return connetion.getData();}public void  delete(final String key){connetion.sendCommand(RedisRepEnum.GETDEL,key.getBytes(StandardCharsets.UTF_8));}//封装redis的过期时间public void expire(String key, long seconds){connetion.sendCommand(RedisRepEnum.EXISTS, key.getBytes(StandardCharsets.UTF_8), Protocol.toByteArray(seconds));}//是否存在keypublic boolean exists(final String key) {connetion.sendCommand(RedisRepEnum.EXISTS, key.getBytes(StandardCharsets.UTF_8));return (Long)connetion.getData()==1L;}//查找key中set包含public Set<String> keys(final String key){connetion.sendCommand(RedisRepEnum.KEYS,key.getBytes(StandardCharsets.UTF_8));return (Set) BuilderFactory.STRING_SET.build((List)connetion.getData());}
}

rpc框架核心代码

package com.trench.protocol;import com.trench.SerializeUtils;
import com.trench.frawork.Invocation;
import com.trench.nacos.dome.NacosHttp;
import org.apache.commons.io.IOUtils;import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;public class HttpClient {public String send(String hostName, Integer port, Invocation invocation) throws IOException {//读取nacos中的配置用户的请求方式。如http   POST get等NacosHttp nacosHttp=new NacosHttp();try {URL url=new URL(nacosHttp.getHttp(),hostName,port,nacosHttp.getFile());HttpURLConnection httpURLConnection=  (HttpURLConnection)url.openConnection();httpURLConnection.setRequestMethod(nacosHttp.getRequestMethod());httpURLConnection.setDoOutput(true);//配置OutputStream outputStream=httpURLConnection.getOutputStream();ObjectOutputStream oss = new ObjectOutputStream(outputStream);oss.writeObject(SerializeUtils.serialize(invocation));oss.flush();oss.close();InputStream inputStream = httpURLConnection.getInputStream();return (String) SerializeUtils.deSerialize(IOUtils.toString(inputStream).getBytes(StandardCharsets.UTF_8));} catch (MalformedURLException e) {throw e;} catch (IOException e) {throw e;}}
}
启动tomcat
package com.trench.protocol;import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;public class HttpServer {public void start(String hostname,Integer port){//读取用户配置Tomcat tomcat=new Tomcat();Server server = tomcat.getServer();Service service = server.findService("Tomcat");Connector connector=new Connector();connector.setPort(port);Engine engine=new StandardEngine();engine.setDefaultHost(hostname);Host host=new StandardHost();host.setName(hostname);String contextPash="";Context context=new StandardContext();context.setPath(contextPash);context.addLifecycleListener(new Tomcat.FixContextListener());host.addChild(context);engine.addChild(host);service.setContainer(engine);service.addConnector(connector);tomcat.addServlet(contextPash,"dispatcher",new DispatcherServlet());context.addServletMappingDecoded("/*","dispatcher");try {tomcat.start();tomcat.getServer().await();}catch (LifecycleException e){e.printStackTrace();}}
}
package com.trench.protocol;import com.trench.frawork.Invocation;
import com.trench.register.LocalRegister;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;public class HttpServerHandler extends HttpServer {public void handler(HttpServletRequest request, HttpServletResponse response){//可自行添加为心跳监听等操作//处理请求try {Invocation invocation = (Invocation)new ObjectInputStream(request.getInputStream()).readObject();String interfaceName =invocation.getInterfaceName();//接口名称Class aClass = LocalRegister.get(interfaceName,invocation.getVersion());Method method = aClass.getMethod(invocation.getMethodName(), invocation.getParameterTypes());String invoke = (String) method.invoke(aClass.newInstance(), invocation.getParameter());IOUtils.write(invoke.getBytes(StandardCharsets.UTF_8),response.getOutputStream());} catch (IOException e) {e.printStackTrace();}catch (ClassNotFoundException e){e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}
}

相关的gitub仓库地址:(https://github.com/zhaoyiwen-wuxian/RpcTrench.git) master分支,进行切换分支到master

相关文章:

手写rpc和redis

rpc框架搭建 consumer 消费者应用 provider 提供的服务 Provider-common 公共类模块 rpc 架构 service-Registration 服务发现 nacos nacos配置中心 load-balancing 负载均衡 redis-trench 手写redis实现和链接 package com.trench.protocol;import com.trench.enumUtil.Redis…...

Unity动画桢事件

1&#xff0c;使用原因 在新项目内部审核的时候&#xff0c;说什么动画节奏不匹配&#xff0c;所以决定用动画桢事件来处理技能释放。当释放技能的时候&#xff0c;先播放技能动画&#xff0c;然后再动画桢所在的时间戳执行技能的逻辑。 2&#xff0c;具体实现 1&#xff0c;…...

搭建Redis集群

一 应用场景 为什么需要redis集群&#xff1f; 当主备复制场景&#xff0c;无法满足主机的单点故障时&#xff0c;需要引入集群配置。 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优化数据库可以采用读写分离的策略。我们可以部 署一台…...

C语言sizeof 不是函数吗?

一、问题 sizeof 怎么⽤&#xff0c;它不是函数吗&#xff1f; 二、解答 sizeof 在 C 和 C 中不是一个函数&#xff0c;而是一个运算符。它在编译时计算其操作数所占用的内存大小&#xff0c;并返回一个大小&#xff08;字节数&#xff09;&#xff0c;这个结果是类型或表达式…...

Mybatis的XML配置

MyBatis 是一个持久层框架&#xff0c;通过 XML 配置文件来定义 SQL 映射和结果的映射规则。以下是关于 MyBatis XML 配置文件的详细说明&#xff1a; 基本结构&#xff1a; XML 配置文件通常包含 <mapper>、<resultMap>、<typeAliases> 等元素。 2. mappe…...

Oracle报错:ORA-08002: sequence CURRVAL is not yet defined in this session

问题 直接查询序列的当前值&#xff0c;然后报了这个错误。 SELECT HR.EMPLOYEES_SEQ.CURRVAL; ORA-08002: sequence CURRVAL is not yet defined in this session解决 ORA-08002错误是Oracle数据库中的一个常见错误&#xff0c;它表示在当前会话中未定义序列的CURRVAL值。这…...

python10-Python的字符串之拼接字符串

如果直接将两个字符串紧挨着写在一起&#xff0c;Python就会自动拼接它们&#xff0c;例如如下代码。 s1 "软件测试划水老师傅&#xff0c;"软件测试老痞print(s1) 上面代码将会输出: 软件测试划水老师傅&#xff0c;软件测试老痞 上面这种写法只是书写字符串的一…...

华为三层交换机之基本操作

Telnet简介 Telnet是一个应用层协议,可以在Internet上或局域网上使用。它提供了基于文本的远程终端接口&#xff0c;允许用户在本地计算机上登录到远程计算机&#xff0c;然后像在本地计算机上一样使用远程计算机的资源。Telnet客户端和服务器之间的通信是通过Telnet协议进行的…...

IntelliJ IDEA 快捷键大全

IntelliJ IDEA 快捷键大全 一、文本编辑二、构建、编译项目 一、文本编辑 CtrlN 查找类 CtrlN 查找文件 CtrlF 查找文本 可以根据需求去选择红框内的选项 CtrlX 剪切 剪切选中文本&#xff0c;如果未选中则剪切当前行CtrlC 复制 复制选中文本&#xff0c;如果未选中则复制当前…...

scrapy的概念作用和工作流程

1. scrapy的概念 Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。 Scrapy 使用了Twisted[twɪstɪd]异步网络框架&#xff0c;可以加快我们的下载速度。 Scrapy文档地址&#xff1a;http://scrapy-chs.readthedocs.io/zh_…...

首页热卖推荐商品显示axios异步请求数据动态渲染实现

flex-wrap属性&#xff1a; 默认情况下&#xff0c;项目都排在一条线&#xff08;又称“轴线”&#xff09;上。flex- wrap属性定义&#xff0c;如果一条轴线 排不下&#xff0c;如何换行&#xff1f; flex-wrap:wrap 该样式用于设置 换行。 .product_name{white-space: nowrap…...

【C++11并发】mutex 笔记

简介 在多线程中往往需要访问临界资源&#xff0c;C11为我们提供了mutex等相关类来保护临界资源&#xff0c;保证某一时刻只有一个线程可以访问临界资源。主要包括各种mutex&#xff0c;他们的命名大都是xx_mutex。以及RAII风格的wrapper类&#xff0c;RAII就是一般在构造的时…...

洛谷 P5635 【CSGRound1】天下第一

原址链接 P5635 【CSGRound1】天下第一 先看标签 搜索&#xff1f;模拟&#xff1f;用不着这么复杂 创建函数a(int x,int y,int p) a(int x,int y,int p){if(x<0){return 1;}x (xy)%p;if(y<0){return 2;}y (xy)%p;return a(x,y,p); }写入主函数 #include<iostrea…...

如何通过Navicat远程访问宝塔面板安装的MySQL数据库

Navicat报错信息&#xff1a; 错误代码 1045 Access denied for user ‘root’’219.144.205.81’ (using password:YES) —— 没有权限的访问的报错 1.宝塔面板 > 放行端口:3306 2.阿里云安全组 > 放行端口:3306 3.配置mysql3306端口 4.使用Xshell 链接服务器 m…...

【硅谷甄选】导航守卫(进度条,网页标题,路由鉴权)

import setting from /setting import router from /router // 任意路由切换实现进度条业务&#xff1a; nprogress插件 import nprogress from nprogress // js插件在ts中的报错 // 引入进度条样式 import nprogress/nprogress.css // 表示在加载进度条时不显示加载小图标 np…...

OpenHarmony—TypeScript到ArkTS约束说明

对象的属性名必须是合法的标识符 规则&#xff1a;arkts-identifiers-as-prop-names 级别&#xff1a;错误 在ArkTS中&#xff0c;对象的属性名不能为数字或字符串。通过属性名访问类的属性&#xff0c;通过数值索引访问数组元素。 TypeScript var x { name: x, 2: 3 };c…...

蓝桥杯——每日一练(简单题)

题目 有n个整数&#xff0c;使前面各数顺序向后移m个位置&#xff0c;最后m个数变成前面m个数。写一函数&#xff1a;实现以上功能&#xff0c;在主函数中输入n个数和输出调整后的n个数。 解析 一、list&#xff08;&#xff09;函数配合map&#xff08;&#xff09;函数获得…...

css设置不可点击

文章目录 一、前言二、MDN三、使用四、注意五、总结六、最后 一、前言 在网页开发中&#xff0c;经常会遇到一种情况&#xff0c;就是需要将某个元素的点击事件屏蔽&#xff0c;使其在用户点击时没有任何反应。这时候&#xff0c;我们可以通过CSS的pointer-events属性设置为no…...

fastapi学习

fastapi框架 fastapi&#xff0c;一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的web框架。 fastapi是建立在Starlette和Pydantic基础上的&#xff0c;Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库。Starlette是一种轻量级的ASGI框架/工…...

【代码随想录-数组】长度最小的子数组

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...