【手写一个RPC框架】simpleRPC-07

2023-11-08

在这里插入图片描述

本项目所有代码可见:https://github.com/weiyu-zeng/SimpleRPC

前言

在simpleRPC-07中,我们为注册的服务接口提供一个负载均衡模块,

实现

zookeeper

在simpleRPC-06时我们安装了zookeeper

这里我们还要把zookeeper打开:

在这里插入图片描述
在这里插入图片描述
启动成功之后,我们再去开客户端:

在这里插入图片描述
点回车,输入 ls /
在这里插入图片描述
我们之前的MyRPC还在,ok的,继续写代码

项目创建

创建名为simpleRPC-07的module,然后在java下创建com.rpc的package

在这里插入图片描述
然后我们回到simpleRPC-06,把com.rpc中的所有内容,复制一下:

在这里插入图片描述

然后回到simpleRPC-07中的com.rpc,粘贴过来:

在这里插入图片描述

然后记得把log4j的配置文件也复制过来:

在这里插入图片描述
在这里插入图片描述

依赖配置

依赖配置跟simpleRPC-06也是一样的:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SimpleRPC</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>simpleRPC-07</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.51.Final</version>
        </dependency>

        <!-- 阿里的fastjson序列化框架 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.67</version>
        </dependency>

        <!--这个jar包应该依赖log4j,不引入log4j会有控制台会有warn,但不影响正常使用-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.13.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.30</version>
        </dependency>
    </dependencies>
</project>

到此为止,simpleRPC-07的内容和simpleRPC-06是一样的了。

记得reload一下maven,我一般喜欢这样:

在这里插入图片描述

loadbalance

创建一个loadbalance 的package:

在这里插入图片描述

我们定义负载均衡接口:LoadBalance.java:

package com.rpc.loadbalance;

import java.util.List;

public interface LoadBalance {
    String balance(List<String> addressList);
}

我们编写随机负载均衡:

RandomLoadBalance.java

package com.rpc.loadbalance;

import java.util.List;
import java.util.Random;

/**
 * 随机负载均衡
 */
public class RandomLoadBalance implements LoadBalance {
    @Override
    public String balance(List<String> addressList) {
        Random random = new Random();
        int choose = random.nextInt(addressList.size());
        System.out.println("负载均衡选择了" + choose + "服务器");
        return addressList.get(choose);
    }
}

我们编写轮询负载均衡:

RoundLoadBalance.java

package com.rpc.loadbalance;

import java.util.List;

/**
 * 轮询负载均衡
 */
public class RoundLoadBalance implements LoadBalance{
    private int choose = -1;

    @Override
    public String balance(List<String> addressList) {
        choose++;
        choose = choose % addressList.size();  // 索引
        System.out.println("负载均衡选择了" + choose + "服务器");
        return addressList.get(choose);  //
    }
}

register

ZkServiceRegister.java

package com.rpc.register;

import com.rpc.loadbalance.LoadBalance;
import com.rpc.loadbalance.RoundLoadBalance;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * @author weiyu_zeng
 */
public class ZkServiceRegister implements ServiceRegister {

    // curator 提供的zookeeper客户端
    private CuratorFramework client;

    // zookeeper根路径结点
    private static final String ROOT_PATH = "MyRPC";

    // 初始化负载均衡器, 这里用的是随机, 一般通过构造函数传入
    private LoadBalance loadBalance = new RoundLoadBalance();

    // 构造方法
    // 这里负责zookeeper客户端的初始化,并与zookeeper服务端建立连接。
    // 初始化包括指定重连策略,指定连接zookeeper的端口,指定超时时间,指定命名空间
    // 初始化完成之后start()开启zookeeper客户端。
    public ZkServiceRegister() {

        // 重连策略:指数时间重试
        RetryPolicy policy = new ExponentialBackoffRetry(1000, 3);

        // zookeeper的地址固定,不管是服务提供者还是消费者,都要与之建立连接
        // sessionTimeoutMs 与 zoo.cfg中的tickTime 有关系,
        // zk还会根据minSessionTimeout与maxSessionTimeout两个参数重新调整最后的超时值。默认分别为tickTime 的2倍和20倍
        // 使用心跳监听状态
        this.client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
                                             .sessionTimeoutMs(40000)
                                             .retryPolicy(policy)
                                             .namespace(ROOT_PATH)
                                             .build();
        this.client.start();
        System.out.println("zookeeper 连接成功");
    }

    // 注册:传入服务方法名(String),传入主机名和端口号的套接字地址(InetSocketAddress)
    @Override
    public void register(String serviceName, InetSocketAddress serverAddress) {
        try {
            // serviceName创建成永久节点,服务提供者下线时,不删服务名,只删地址
            Stat stat = client.checkExists().forPath("/" + serviceName);
            if (stat == null) {
                client.create()
                        .creatingParentsIfNeeded()
                        .withMode(CreateMode.PERSISTENT)
                        .forPath("/" + serviceName);
            }
            // 路径地址,一个/代表一个节点
            String path = "/" + serviceName + "/" + getServiceAddress(serverAddress);
            // 临时节点,服务器下线就删除节点
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
        } catch (Exception e) {
            System.out.println("此服务已存在");
        }
    }

    // 根据服务名返回地址
    @Override
    public InetSocketAddress serviceDiscovery(String serviceName) {
        try {
            List<String> strings = client.getChildren().forPath("/" + serviceName);
            // 负载均衡选择器,选择一个
            String string = loadBalance.balance(strings);
//            String string = strings.get(0);
            return parseAddress(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 地址 -> XXX.XXX.XXX.XXX:port 字符串
    private String getServiceAddress(InetSocketAddress serverAddress) {
        return serverAddress.getHostName() + ":" + serverAddress.getPort();
    }

    // 字符串解析为地址:按照":"切分开,前半是host(String),后半是port(int)
    private InetSocketAddress parseAddress(String address) {
        String[] result = address.split(":");
        return new InetSocketAddress(result[0], Integer.parseInt(result[1]));
    }
}

client

和simpleRPC-06 一样

codec

和simpleRPC-06 一样

common

和simpleRPC-06 一样

service

和simpleRPC-06 一样

server

和simpleRPC-06 一样

文件结构

文件结构如下:

在这里插入图片描述

在这里插入图片描述

运行

先确认一下zookeeper server还在开启,否则可能卡在这个地方

zookeeper 连接成功

先运行TestServer.java:
在这里插入图片描述
我们在simpleRPC-06中已经注册了服务,所以显示User 和 Blog的两个服务已存在。

然后运行TestClient.java:
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【手写一个RPC框架】simpleRPC-07 的相关文章

  • Mass-Bruter:一款功能强大的网络常用服务爆破枚举工具

    关于Mass Bruter Mass Bruter是一款功能强大的网络常用服务爆破枚举工具 该工具本质上是一个简单的PoC项目 可以帮助广大研究人员快速在大规模网络系统中执行常见服务爆破枚举 该工具专为红队研究人员设计 支持检测FTP SS
  • 第八章 确认访问用户身份的认证

    第八章 确认访问用户身份的认证 8 1 何为认证 在计算机安全和网络通信的背景下 认证是 确认实体 如用户 计算机系统 服务 身份真实性的过程 认证是确保系统只对合法用户或实体开放访问权限的一种关键机制 在网络通信中 认证通常涉及验证用户或
  • PDH光端机技术与应用:稳定可靠的数据传输解决方案

    在当今数字化 网络化日益加速的世界中 数据传输的稳定性和可靠性至关重要 PDH Plesiochronous Digital Hierarchy 准同步数字系列 光端机技术 作为早期的数字传输系统之一 虽然已被更先进的SDH Synchro
  • 通过一个寒假能学会黑客技术吗?看完你就知道了

    一个寒假能成为黑客吗 资深白帽子来告诉你 如果你想的是学完去美国五角大楼内网随意溜达几圈 想顺走一点机密文件的话 劝你还是趁早放弃 但是成为一名初级黑客还是绰绰有余的 你只需要掌握好渗透测试 Web安全 数据库 搞懂web安全防护 SQL注
  • 毕业设计 HTTP 自助服务

    目录 项目 HTTP 自助服务 介绍 项目展示 背景知识 HTTP 协议 HTTP自主服务编写 sock 套接字编写 Tcp 服务器编写 小组件 锁守卫 lockGuard 测试Tcp服务器运行 编写 HTTP 服务 Tcp 服务中获取监听
  • 6类典型场景的无线AP选型和部署方案

    你们好 我的网工朋友 前段时间刚给你们来了篇解决无线频繁断网的技术文 解决无线频繁断网 这个办法值得收藏 不少朋友私聊 说想再聊聊无线AP的选型和部署方案 这不就安排上了 无线网络覆盖项目中 无线AP的合理选型和部署非常重要 在设计施工中
  • WEB前端常见受攻击方式及解决办法总结

    一个网址建立后 如果不注意安全问题 就很容易被人攻击 下面讨论一下集中漏洞情况和放置攻击的方法 一 SQL注入 所谓的SQL注入 就是通过把SQL命令插入到web表单提交或输入域名或页面请求的查询字符串 最终达到欺骗服务器执行恶意的SQL命
  • 用户数据中的幸存者偏差

    幸存者偏差 Survivorship bias 是一种常见的逻辑谬误 意思是没有考虑到筛选的过程 忽略了被筛选掉的关键信息 只看到经过筛选后而产生的结果 先讲个故事 二战时 无奈德国空防强大 盟军战机损毁严重 于是军方便找来科学家统计飞机受
  • 白帽子如何快速挖到人生的第一个漏洞 | 购物站点挖掘商城漏洞

    本文针对人群 很多朋友们接触安全都是通过书籍 网上流传的PDF 亦或是通过论坛里的文章 但可能经过了这样一段时间的学习 了解了一些常见漏洞的原理之后 对于漏洞挖掘还不是很清楚 甚至不明白如何下手 可能你通过 sql labs 初步掌握了sq
  • 2024年金三银四网络安全考试试题

    2023年金三银四网络安全考试试题 1 关于数据使用说法错误的是 A 在知识分享 案例中如涉及客户网络数据 应取敏感化 不得直接使用 B 在公开场合 公共媒体等谈论 传播或发布客户网络中的数据 需获得客户书面授权或取敏感化 公开渠道获得的除
  • 「网络安全渗透」如果你还不懂CSRF?这一篇让你彻底掌握

    1 什么是 CSRF 面试的时候的著名问题 谈一谈你对 CSRF 与 SSRF 区别的看法 这个问题 如果我们用非常通俗的语言讲的话 CSRF 更像是钓鱼的举动 是用户攻击用户的 而对于 SSRF 来说 是由服务器发出请求 用户 日 服务器
  • 通俗易懂,十分钟读懂DES,详解DES加密算法原理,DES攻击手段以及3DES原理

    文章目录 1 什么是DES 2 DES的基本概念 3 DES的加密流程 4 DES算法步骤详解 4 1 初始置换 Initial Permutation IP置换 4 2 加密轮次 4 3 F轮函数 4 3 1 拓展R到48位 4 3 2
  • 【信道估计】【MIMO】【FBMC】未来移动通信的滤波器组多载波调制方案(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • socket网络编程几大模型?看看CHAT是如何回复的?

    CHAT回复 网络编程中常见的有以下几种模型 1 阻塞I O模型 Blocking I O 传统的同步I O模型 一次只处理一个请求 2 非阻塞I O模型 Non blocking I O 应用程序轮询调用socket相关函数检查请求 不需
  • tcpdump抓包

    tcpdump抓包 基本概念 1 类型的关键字 host 指明一台主机 如 host 10 1 110 110 net 指明一个网络地址 如 net 10 1 0 0 port 指明端口号 如 port 8090 2 确定方向的关键字 sr
  • 网工内推 | 上市公司同程、科达,五险一金,年终奖,最高12k*15薪

    01 同程旅行 招聘岗位 网络工程师 职责描述 1 负责职场 门店网络规划 建设 维护 2 负责网络安全及访问控制 上网行为管理和VPN设备的日常运维 3 负责内部相关网络自动化和系统化建设 4 优化与提升网络运行质量 制定应急预案 人员培
  • 没有代理/存根 DLL 的进程外 COM 服务器?

    我正在学习如何实现进程外 COM 服务器 并发现了这篇代码项目文章 构建本地 COM 服务器和客户端 分步示例 http www codeproject com Articles 8679 Building a LOCAL COM Serv
  • 如何通过RPC监听firestore

    我想听firestore中的实时变化 而且我也只允许使用Go 由于 Firestore SDK for Go 没有任何选项来监听实时更改 因此我决定使用 firestore v1beta1 sdk 我编写了以下代码来做到这一点 func T
  • 有没有好的、简单的用于进程间调用的 RPC 库? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • LRPC 的意义何在?为什么有人想要对同一台机器进行远程过程调用?

    根据我对 RPC 远程过程调用 的理解 它们提供了一种向远程计算机发送函数调用 调用等的方法 这样做的明显优点是 您可以拥有一个在机器集群上运行的单个程序 并且可以处理更多请求 更多数据等 但我很困惑LRPC 轻量级RPC http www

随机推荐

  • 在Android中间件JNI层添加调试信息__android_log_print()

    最近做Android新项目的时候需要用到JNI 但是在该层调试程序的时候 C C 的常用的printf和cout这些传统的控制台调试输出无效 因此就需要android特有的终端调试函数 android log print 该函数的调用时需要
  • Python爬虫项目:从pip中安装库到爬取全过程

    通过python爬取目标网站https ncov dxy cn ncovh5 view pneumonia上的全球最新疫情数据和国内最新疫情数据 爬取的数据以json文件的格式保存 通过解析该json文件 将爬取的疫情数据做了两方面的处理
  • 判断闰年(函数)

    define CRT SECURE NO WARNINGS include
  • ElasticSearch High Level REST API【2】搜索查询

    如下为一段带有分页的简单搜索查询示例 在search搜索中大部分的搜索条件添加都可通过设置SearchSourceBuilder来实现 然后将SearchSourceBuilder RestHighLevelClient client El
  • 【leetcode字节跳动题库】121. Best Time to Buy and Sell Stock

    题目 题目链接 提交代码 class Solution public int maxProfit int prices if prices null prices length 0 return 0 int res 0 in prices
  • Linux中man手册的安装以及使用详解

    Linux中man手册的安装以及使用详解 linux中man手册的安装以及使用详解 man手册是什么 man手册是干嘛的 man手册如何安装 man手册如何使用 举例讲解 我们来看一下man手册的目录结构 进行具体分析 section 分析
  • 闭包的使用一些总结

    我们看一下官方对于闭包的解释 走起 闭包 closure 是一个函数以及其捆绑的周边环境状态 lexical environment 词法环境 的引用的组合 换而言之 闭包让开发者可以从内部函数访问外部函数的作用域 在 JavaScript
  • RSA加密算法Python实现

    RSA加密算法Python实现 1 RSA算法简介 2 RSA算法涉及的数学知识 2 1互素 2 2 欧拉定理 2 3求模逆元 2 4 取模运算 2 5 最大公因数 2 6 最小公倍数 2 7 欧几里得算法 2 8 扩展欧几里得算法 3 R
  • 三菱服务器显示d1d2,三菱PLC指令SMOV D2 K2 K2 D1 K3详解

    三菱PLC指令SMOV D2 K2 K2 D1 K3是什么意思 补充 若D2为16H D1为 5H时 组合后的 3位BCD码为什么为165H 为什么是Y010 Y006 Y005 Y002 Y000驱动线圈为ON 这个你看下就能理解了 SM
  • uniapp表单uni-forms校验失败后页面滚动到相应位置

    这里用到的ui框架是uni ui 如果直接使用uView校验失败页面会自动定位到相应位置 1 给uni forms item添加唯一id 我用的是form item的v model方便之后使用 2 在onReady中给form添加校验规则
  • React 基础-书写一个页面

    由于 RN 环境过于麻烦 所以这里先尝试 React 有不对的还望不吝赐教 React 安装请查看官网 渲染 JSX React 的模板语法是 JSX 看起来很像是 JS HTML 的混血儿 具体的语法这里就不再赘述 想了解的话 http
  • GBDT算法梳理

    1 GBDT Gradient Boosting Decision Tree 思想 Boosting 给定初始训练数据 由此训练出第一个基学习器 根据基学习器的表现对样本进行调整 在之前学习器做错的样本上投入更多关注 用调整后的样本 训练下
  • Pythhon消消乐小游戏

    Pythhon消消乐小游戏 一 程序代码 1 游戏介绍 2 游戏代码 二 程序打包成exe程序 1 安装pyinstaller 2 将python文件打包为exe程序 3 打包报错 一 程序代码 1 游戏介绍 开心消消乐是消除类的游戏 适合
  • openwrt --- web密码

    1 设置web密码步骤 登陆web 选择System gt Administration 在Router Password下设置web登陆密码 点击Save Apply保存 2 忘记web密码 通过串口或者SSh登陆 打开文件 vi etc
  • conda 环境导入导出 yaml

    conda中的环境可以导入和导出 导出 conda env export gt environment yaml 导入 conda env create f environment yaml 什么意思呢 就是用conda create n
  • kmalloc用法

    在读代码学习的时候发现有个malloc函数用的很奇怪 跳到定义处查看了一下原理来时一个宏定义 use volatile to fix a probable compiler error on 2 6 25 define malloc siz
  • PCL:从法线计算到曲率计算并可视化

    法线求解原理 表面法线是几何体表面的重要属性 在很多领域都有大量应用 例如 在进行光照渲染时产生符合可视习惯的效果时需要表面法线信息才能正常进行 对于一个已知的几何体表面 根据垂直于点表面的矢量 因此推断表面某一点的法线方向通常比较简单 然
  • 一键部署openvpn服务端和客户端(已写成脚本)

    openvpn 容器安装 需要有docker compse和docker docker和docker compse一键脚本 bin bash 添加DNS echo MASTER IP HOSTNAME gt gt etc hosts DNS
  • SpringCloud + xxl-job 任务调度的简单使用

    概述 xxl job是一个轻量级分布式任务调度平台 其核心设计目标是开发迅速 学习简单 轻量级 易扩展 之前开发的SpringCloud项目 因为其中有个应用有几个定时任务 为了统一管理和更可视化以及监控提醒于是加入了xxl job 好了
  • 【手写一个RPC框架】simpleRPC-07

    目录 前言 实现 zookeeper 项目创建 依赖配置 loadbalance register client codec common service server 文件结构 运行 本项目所有代码可见 https github com