{"id":18559174,"url":"https://github.com/linux-china/rsocket-load-balancing","last_synced_at":"2025-04-10T02:30:41.041Z","repository":{"id":136595904,"uuid":"335780951","full_name":"linux-china/rsocket-load-balancing","owner":"linux-china","description":"RSocket load balancing based on Spring Cloud Service Registry","archived":false,"fork":false,"pushed_at":"2021-02-09T23:29:57.000Z","size":449,"stargazers_count":15,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T02:51:13.277Z","etag":null,"topics":["consul","loadbalancing","rsocket"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linux-china.png","metadata":{"files":{"readme":"README-cn.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-03T23:15:01.000Z","updated_at":"2023-03-13T09:41:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"e1b66e32-3f73-441c-9748-832f4dbca815","html_url":"https://github.com/linux-china/rsocket-load-balancing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-china%2Frsocket-load-balancing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-china%2Frsocket-load-balancing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-china%2Frsocket-load-balancing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-china%2Frsocket-load-balancing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linux-china","download_url":"https://codeload.github.com/linux-china/rsocket-load-balancing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248144158,"owners_count":21054876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consul","loadbalancing","rsocket"],"created_at":"2024-11-06T21:42:13.925Z","updated_at":"2025-04-10T02:30:41.033Z","avatar_url":"https://github.com/linux-china.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"RSocket Load Balancing with Spring Cloud Registry\n=================================================\n\n基于Spring Cloud服务注册发现架构实现RSocket负载均衡，架构如下：\n\n![LoadBalance Structure](loadbalance-structure.png)\n\n# 如何运行?\n\n* 首先启动Consul： `docker-compose up -d consul` ，然后访问 http://localhost:8500\n* 编译整个项目: `mvn -DskipTests clean package`\n* 启动server-app: `java -jar server-app/target/server-app-1.0.0-SNAPSHOT.jar`\n* 启动client-app: `java -jar client-app/target/client-app-1.0.0-SNAPSHOT.jar`\n* 测试服务： `curl http://localhost:9080/square/3`\n\n\n# 应用和服务命名规范\nSpring Cloud的注册发现机制是基于`spring.application.name`，也就是后续的服务查找就是基于该名称进行的。  \n如果你调用`ReactiveDiscoveryClient.getInstances(String serviceId);`查找服务实例列表时，这个serviceId参数其实就是Spring的应用名称。\n考虑到服务注册和后续的RSocket服务路由，所以我们打算设计一个简单的命名规范。\n\n**注意：** 应用名称不能包含\".\"，这个不是合法的DNS主机名，会被Service Registry转换为\"-\"。\n\n假设你有一个服务应用，功能名称为calculator，同时提供两个服务: 数学计算器服务(MathCalculatorService)和汇率计算服务(ExchangeCalculatorService),\n那么我们该如何如何来命名应用？ 这里我们采用Java package命名规范，如 `com-example-calculator`，这样可以确保不会和其他应用重名，另外也方便和Java Package名称进行转换。\n\n那么服务接口应该如何命名？ 服务接口基于应用名称和interface名称构建，规则为 `String serviceName = appName.replace(\"-\", \".\") + \".\" + interfaceName; ` ，\n如下述命名都是合乎规范的：\n\n* com.example.calculator.MathCalculatorService\n* com.example.calculator.ExchangeCalculatorService\n\n而 `com.example.calculator.math.MathCalculatorService` 则是错误的 :x:, 因为在应用名称和接口名称之间多了`math`。\n\n在RSocket的架构中还有另外一种架构方式，就是Broker架构，如果一个RSocket服务提供者同时端口监听和Broker注册，那么如何通过broker来访问该服务？\n这里我们采用一个`broker:`前缀来判断，如缺省的broker集群的应用名称为`broker`, 当然也可以为`broker1`, `broker2`，通过这种添加前缀的方式，我们可以识别出是否要经过Broker进行通讯，\n样例的名称如 `broker:com.example.calculator.MathCalculatorService`。当然你可以可以通过这种方式指定特定的应用名称，如`server-1:com.example.calculator.MathCalculatorService`。\n\n为何要采用这种命名规范？ 首先让我们看一下是如何调用远程RSocket服务的：\n\n* 首先我们根据Service全面提取处对应的应用名称(appName)，如 `com.example.calculator.MathCalculatorService` 服务对应的appName则为`com-example-calculator`\n* 调用`ReactiveDiscoveryClient.getInstances(appName)` 获取应用名对应的实例列表\n* 根据`RSocketRequester.Builder.transports(servers)` 构建具有负载均衡能力的RSocketRequester\n* 使用服务全称作为路由进行RSocketRequester的API调用，样例代码如下：\n\n```\n rsocketRequester.route(\"com.example.calculator.MathCalculatorService.square\")\n                .data(number)\n                .retrieveMono(Integer.class)\n```\n\n通过该种命名方式，我们可以从服务全称中提取中应用名，然后和服务注册中心交互查找对应的实例列表，然后建立和服务提供者的连接，最后基于服务名称进行服务调用。\n\n回到最前面说到的规范，如果应用名和服务接口的绑定关系你实在做不到，那么你可以使用这种方式实现服务调用，  \n如`calculator-server:com.example.calculator.math.MathCalculatorService`，  \n只是你需要更完整的文档说明，当然这种方式也可以解决之前系统接入到目前的架构上，应用的迁移成本也比较小。\n\n\n# References\n\n* YMNNALFT: Easy RPC with RSocket: https://spring.io/blog/2021/01/18/ymnnalft-easy-rpc-with-rsocket\n* Spring Cloud Consul: https://docs.spring.io/spring-cloud-consul/docs/current/reference/html/\n* RSocket Load Balancing: https://www.vinsguru.com/rsocket-load-balancing-client-side/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-china%2Frsocket-load-balancing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinux-china%2Frsocket-load-balancing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-china%2Frsocket-load-balancing/lists"}