---
title: "Solon Rpc 使用注册与发现服务"
---


更多内容可参考：[《Solon Cloud 开发（分布式套件）/使用分布式发现与注册服务》](/article/76)



### 1、 从固定 URL 改成服务名


固定 URL 适合第一次调用；服务实例变多、地址经常变化后，客户端应使用：

```text
name + path → LoadBalance/Discovery → 某个实例的 URL + path
```




固定地址：

```java
@NamiClient(url = "http://localhost:9001/rpc/v1/user", headers = ContentTypes.JSON)
UserService userService;
```

（改变）服务名方式：

```java
@NamiClient(name = "userapi", path = "/rpc/v1/user", headers = ContentTypes.JSON)
UserService userService;
```

`url` 与 `name/path` 是两种寻址方式。不要同时把它们当作两个独立地址配置；实际选哪一个应按你的发现方案约定。


### 2、使用本地发现服务（适合学习）


* 服务端

不需要改造，也不需要注册。

* 客户端，改造

引入 solon-cloud 插件依赖（自带了本地发现能力）。修改应用配置：

```yaml
solon.cloud.local:
  discovery:
    service:
      userapi: #添加本地服务发现（userapi 为服务名）
        - "http://localhost:8081"
```


服务使用的地方改造一下：

```java
@Mapping("user")
public class UserController {
    //直接指定地址和序列化方案（旧的不要了）
    //@NamiClient(url = "http://localhost:9001/rpc/v1/user", headers = "Content-Type=application/json")
    
    //指定服务名、路径和序列化方案（新的不用关注服务地址）
    @NamiClient(name = "userapi",  path="/rpc/v1/user", headers=ContentTypes.JSON)
    UserService userService;
    
    @Post
    @Mapping("register")
    public Result register(User user){
        //调用远程服务，添加用户
        userService.add(user);
        
        return Result.succeed();
    }
   
}
```



### 3、使用分布式（中间件）注册与发现服务


以某个 Cloud Discovery 插件为例，服务端负责注册自身，客户端负责查询实例。两端通常需要：

1. 引入相同注册中心插件。
2. 配置相同的注册中心地址。
3. 确认 group、name、namespace 等标识一致。
4. 确认服务端暴露地址是客户端可访问的地址。
5. 确认健康检查和实例状态正常。

注册中心配置不是 Nami 本身的固定 API；Nacos、Water、Consul、ZooKeeper 等插件的坐标和配置不同，不应混写。



下面使用 water-solon-cloud-plugin 做为注册与发现服务。其它的 solon cloud 注册与服务插件都可。

* 服务端项目，改造

引入 water-solon-cloud-plugin 插件依赖（或者别的注册与发现服务）。修改应用配置：

```yml
server.port: 9001

solon.app:
  group: "demo"
  name: "userapi"
  
solon.cloud.water:
  server: "waterapi:9371"
```

其它不用动。


* 客户端项目，改造


引入 water-solon-cloud-plugin 插件依赖。修改应用配置：

```yml
server.port: 8081

solon.app:
  group: "demo"
  name: "userdemo"
  
solon.cloud.water:
  server: "waterapi:9371"
```

服务使用的地方改造一下：

```java
@Mapping("user")
public class UserController {
    //直接指定地址和序列化方案（旧的不要了）
    //@NamiClient(url = "http://localhost:9001/rpc/v1/user", headers = "Content-Type=application/json")
    
    //指定服务名、路径和序列化方案（新的不用关注服务地址）
    @NamiClient(name = "userapi",  path="/rpc/v1/user", headers=ContentTypes.JSON)
    UserService userService;
    
    @Post
    @Mapping("register")
    public Result register(User user){
        //调用远程服务，添加用户
        userService.add(user);
        
        return Result.succeed();
    }
   
}
```

打包后，启动服务。(要在water环境下运行)

```shell
java -jar userdemo.jar
```



### 4、排错方法（先本地再分布式）

出现问题时，可以按这个顺序排错。

```text
固定 URL 能否调用？
      ↓ 能
本地 name 映射能否调用？
      ↓ 能
再接入分布式注册中心
      ↓
最后检查多实例和负载策略
```

如果固定 URL 成功、服务名失败，业务接口通常没有问题，重点检查发现插件、服务名、分组和实例地址。


### 5、代码演示（演示与文档内容略不同）

* [demo7003_rpc_sml_nacos](https://gitee.com/noear/solon-examples/tree/main/7.Solon-Remoting-Rpc/demo7003_rpc_sml_nacos)
* [demo7004-rpc_sml_zk](https://gitee.com/noear/solon-examples/tree/main/7.Solon-Remoting-Rpc/demo7004-rpc_sml_zk)
