手写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,使用原因 在新项目内部审核的时候,说什么动画节奏不匹配,所以决定用动画桢事件来处理技能释放。当释放技能的时候,先播放技能动画,然后再动画桢所在的时间戳执行技能的逻辑。 2,具体实现 1,…...
搭建Redis集群
一 应用场景 为什么需要redis集群? 当主备复制场景,无法满足主机的单点故障时,需要引入集群配置。 一般数据库要处理的读请求远大于写请求 ,针对这种情况,我们优化数据库可以采用读写分离的策略。我们可以部 署一台…...
C语言sizeof 不是函数吗?
一、问题 sizeof 怎么⽤,它不是函数吗? 二、解答 sizeof 在 C 和 C 中不是一个函数,而是一个运算符。它在编译时计算其操作数所占用的内存大小,并返回一个大小(字节数),这个结果是类型或表达式…...
Mybatis的XML配置
MyBatis 是一个持久层框架,通过 XML 配置文件来定义 SQL 映射和结果的映射规则。以下是关于 MyBatis XML 配置文件的详细说明: 基本结构: XML 配置文件通常包含 <mapper>、<resultMap>、<typeAliases> 等元素。 2. mappe…...
Oracle报错:ORA-08002: sequence CURRVAL is not yet defined in this session
问题 直接查询序列的当前值,然后报了这个错误。 SELECT HR.EMPLOYEES_SEQ.CURRVAL; ORA-08002: sequence CURRVAL is not yet defined in this session解决 ORA-08002错误是Oracle数据库中的一个常见错误,它表示在当前会话中未定义序列的CURRVAL值。这…...
python10-Python的字符串之拼接字符串
如果直接将两个字符串紧挨着写在一起,Python就会自动拼接它们,例如如下代码。 s1 "软件测试划水老师傅,"软件测试老痞print(s1) 上面代码将会输出: 软件测试划水老师傅,软件测试老痞 上面这种写法只是书写字符串的一…...
华为三层交换机之基本操作
Telnet简介 Telnet是一个应用层协议,可以在Internet上或局域网上使用。它提供了基于文本的远程终端接口,允许用户在本地计算机上登录到远程计算机,然后像在本地计算机上一样使用远程计算机的资源。Telnet客户端和服务器之间的通信是通过Telnet协议进行的…...
IntelliJ IDEA 快捷键大全
IntelliJ IDEA 快捷键大全 一、文本编辑二、构建、编译项目 一、文本编辑 CtrlN 查找类 CtrlN 查找文件 CtrlF 查找文本 可以根据需求去选择红框内的选项 CtrlX 剪切 剪切选中文本,如果未选中则剪切当前行CtrlC 复制 复制选中文本,如果未选中则复制当前…...
scrapy的概念作用和工作流程
1. scrapy的概念 Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。 Scrapy 使用了Twisted[twɪstɪd]异步网络框架,可以加快我们的下载速度。 Scrapy文档地址:http://scrapy-chs.readthedocs.io/zh_…...
首页热卖推荐商品显示axios异步请求数据动态渲染实现
flex-wrap属性: 默认情况下,项目都排在一条线(又称“轴线”)上。flex- wrap属性定义,如果一条轴线 排不下,如何换行? flex-wrap:wrap 该样式用于设置 换行。 .product_name{white-space: nowrap…...
【C++11并发】mutex 笔记
简介 在多线程中往往需要访问临界资源,C11为我们提供了mutex等相关类来保护临界资源,保证某一时刻只有一个线程可以访问临界资源。主要包括各种mutex,他们的命名大都是xx_mutex。以及RAII风格的wrapper类,RAII就是一般在构造的时…...
洛谷 P5635 【CSGRound1】天下第一
原址链接 P5635 【CSGRound1】天下第一 先看标签 搜索?模拟?用不着这么复杂 创建函数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报错信息: 错误代码 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 // 任意路由切换实现进度条业务: nprogress插件 import nprogress from nprogress // js插件在ts中的报错 // 引入进度条样式 import nprogress/nprogress.css // 表示在加载进度条时不显示加载小图标 np…...
OpenHarmony—TypeScript到ArkTS约束说明
对象的属性名必须是合法的标识符 规则:arkts-identifiers-as-prop-names 级别:错误 在ArkTS中,对象的属性名不能为数字或字符串。通过属性名访问类的属性,通过数值索引访问数组元素。 TypeScript var x { name: x, 2: 3 };c…...
蓝桥杯——每日一练(简单题)
题目 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数。写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数。 解析 一、list()函数配合map()函数获得…...
css设置不可点击
文章目录 一、前言二、MDN三、使用四、注意五、总结六、最后 一、前言 在网页开发中,经常会遇到一种情况,就是需要将某个元素的点击事件屏蔽,使其在用户点击时没有任何反应。这时候,我们可以通过CSS的pointer-events属性设置为no…...
fastapi学习
fastapi框架 fastapi,一个用于构建 API 的现代、快速(高性能)的web框架。 fastapi是建立在Starlette和Pydantic基础上的,Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库。Starlette是一种轻量级的ASGI框架/工…...
【代码随想录-数组】长度最小的子数组
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
