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

【RPC注册发现框架实战】一个简易的RPC注册发现框架

Java实现 服务端起10个线程ID监听40-49这10个端口,这10个端口注册到注册中心,提供同一个服务,发个A,响应B,客户端起10个线程去注册中心请求
好的,我们可以通过实现一个简单的服务端、注册中心和客户端来达到这个目的。以下是详细的代码示例:

服务端代码

import java.io.*;
import java.net.*;
import java.util.concurrent.*;public class MultiPortServer {private static final int PORT_START = 40;private static final int PORT_END = 49;private static final ExecutorService executor = Executors.newFixedThreadPool(PORT_END - PORT_START + 1);public static void main(String[] args) {for (int port = PORT_START; port <= PORT_END; port++) {int finalPort = port;executor.submit(() -> startServer(finalPort));RegistryCenter.registerService(finalPort, "localhost");}}private static void startServer(int port) {try (ServerSocket serverSocket = new ServerSocket(port)) {System.out.println("Server listening on port " + port);while (true) {Socket clientSocket = serverSocket.accept();handleClient(clientSocket);}} catch (IOException e) {e.printStackTrace();}}private static void handleClient(Socket clientSocket) {try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {String message = in.readLine();if ("A".equals(message)) {out.println("B");} else {out.println("Unknown message");}} catch (IOException e) {e.printStackTrace();}}
}

注册中心代码

import java.util.*;
import java.util.concurrent.*;public class RegistryCenter {private static final Map<Integer, String> serviceRegistry = new ConcurrentHashMap<>();public static void registerService(int port, String address) {serviceRegistry.put(port, address);System.out.println("Service registered on port " + port + " at address " + address);}public static String lookupService(int port) {return serviceRegistry.get(port);}public static List<Integer> getAllServicePorts() {return new ArrayList<>(serviceRegistry.keySet());}
}

客户端代码

import java.io.*;
import java.net.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Client {private static final int CLIENT_COUNT = 10;private static final ExecutorService executor = Executors.newFixedThreadPool(CLIENT_COUNT);public static void main(String[] args) {List<Integer> servicePorts = RegistryCenter.getAllServicePorts();for (int i = 0; i < CLIENT_COUNT; i++) {executor.submit(() -> {int portIndex = (int) (Math.random() * servicePorts.size());int servicePort = servicePorts.get(portIndex);queryService(servicePort);});}executor.shutdown();}private static void queryService(int servicePort) {String serviceAddress = RegistryCenter.lookupService(servicePort);if (serviceAddress != null) {try (Socket socket = new Socket(serviceAddress, servicePort);PrintWriter out = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {out.println("A");String response = in.readLine();System.out.println("Response from server on port " + servicePort + ": " + response);} catch (IOException e) {e.printStackTrace();}} else {System.out.println("No service found on port " + servicePort);}}
}

运行步骤

  1. 启动服务端

    • 运行 MultiPortServer 类。它将启动10个线程,每个线程监听一个端口(40-49),并将这些服务注册到注册中心。
  2. 启动客户端

    • 运行 Client 类。它将启动10个客户端线程,每个线程随机选择一个服务端口,从注册中心获取该端口的服务地址,并发送消息 “A”。

说明

  1. 服务端

    • MultiPortServer 类创建一个线程池,每个线程监听一个特定端口,并将该端口的服务注册到 RegistryCenter
    • 每个服务端口接收到消息 “A” 后,响应消息 “B”。
  2. 注册中心

    • RegistryCenter 类负责管理服务的注册和查询。
    • 提供了 registerService 方法用于注册服务,lookupService 方法用于查询服务地址,getAllServicePorts 方法用于获取所有注册的服务端口。
  3. 客户端

    • Client 类创建一个线程池,启动10个客户端线程,每个线程随机选择一个服务端口,向服务端发送消息 “A”,并打印服务端的响应。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Vue.js:如何区分页面关闭和刷新?深入解析与实战
  • mysql命令练习
  • 测试开发面经总结(三)
  • Qt篇——QSqlQueryModel内容居中显示
  • Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图
  • 服务器的80和443端口关闭也能申请SSL证书
  • 容器安全最佳实践和工具
  • 系统架构设计师教程 第3章 信息系统基础知识-3.5 专家系统-解读
  • Vue--Router(路由)
  • Scrapy 核心组件之Spiders组件的使用
  • java在继承的继承上添加新的属性和方法
  • 通过MobaXterm工具远程连接可视化服务器桌面并操控
  • [React 进阶系列] useSyncExternalStore hook
  • 华为OD机考题(HJ90 合法IP)
  • Laravel Passport:API认证的瑞士军刀
  • CSS 专业技巧
  • CSS实用技巧干货
  • javascript面向对象之创建对象
  • js继承的实现方法
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • mysql常用命令汇总
  • ReactNative开发常用的三方模块
  • unity如何实现一个固定宽度的orthagraphic相机
  • WebSocket使用
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 给新手的新浪微博 SDK 集成教程【一】
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 微服务入门【系列视频课程】
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 消息队列系列二(IOT中消息队列的应用)
  • 因为阿里,他们成了“杭漂”
  • 如何用纯 CSS 创作一个货车 loader
  • ​Linux·i2c驱动架构​
  • # Panda3d 碰撞检测系统介绍
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (Java入门)学生管理系统
  • (LeetCode C++)盛最多水的容器
  • (二)linux使用docker容器运行mysql
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (转)Oracle 9i 数据库设计指引全集(1)
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Reactor简单使用教程
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .Net 代码性能 - (1)
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET处理HTTP请求
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?