RPC-BDY(4)-nacos注册中心

RPC-BDY(4)

-2022.7.19



前言

这一节的主要内容是将注册中心更改为nacos
原因:原有的框架服务端的地址固定,对于一个客户端,它只会去寻找那么一个服务提供者,如果这个提供者挂了或者换了地址,那就没有办法了。
实现nacos后,如果拿来的这个挂了,还可以重新请求,并且在这种情况下可以很方便地实现负载均衡。


一、nacos

1.简介:

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速 实现动态服务发现、服务配置、服务元数据及流量管理。

2.实现:

在RPC框架中,通过核心组件namingService来实现nacos的连接注册和获取

连接

 //通过 NamingFactory 创建 NamingService 连接 Nacos
            namingService = NamingFactory.createNamingService(SERVER_ADDR);

注册

 namingService.registerInstance(serviceName, inetSocketAddress.getHostName(), inetSocketAddress.getPort());

获取

 List<Instance> instances =  namingService.getAllInstances(serviceName);
            //这里为什么要get0
            //通过 getAllInstance 获取到某个服务的所有提供者列表后,需要选择一个,这里就涉及了负载均衡策略,这里我们先选择第 0 个,后面某节会详细讲解负载均衡。
            Instance instance = instances.get(0);
            return new InetSocketAddress(instance.getIp(), instance.getPort());

二、nacos使用

  1. 运行(linux)
sh startup.sh -m standalone
  1. 引入依赖
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.3.0</version>
        </dependency>

  1. 实现注册类

通过 NamingFactory 创建 NamingService 连接 Nacos并实现注册和发现

  • ServiceRegistry注册接口
public interface ServiceRegistry {
    void register(String serviceName, InetSocketAddress inetSocketAddress);
    InetSocketAddress lookupService(String serviceName);
}

  • NacosServiceRegistry注册实现类
/**
 * Nacos服务注册中心
 * @author bdy
 */
public class NacosServiceRegistry implements ServiceRegistry{

    private static final Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class);

    private static final String SERVER_ADDR = "127.0.0.1:8848";
    private static final NamingService namingService;


    static {
        try {
            //通过 NamingFactory 创建 NamingService 连接 Nacos
            namingService = NamingFactory.createNamingService(SERVER_ADDR);
        } catch (NacosException e) {
            logger.error("连接到Nacos时有错误发生: ", e);
            throw new RpcException(RpcError.FAILED_TO_CONNECT_TO_SERVICE_REGISTRY);
        }
    }


    @Override
    public void register(String serviceName, InetSocketAddress inetSocketAddress) {
        try {
            namingService.registerInstance(serviceName, inetSocketAddress.getHostName(), inetSocketAddress.getPort());
        } catch (NacosException e) {
            logger.error("注册服务时有错误发生:", e);
            throw new RpcException(RpcError.REGISTER_SERVICE_FAILED);
        }
    }

    @Override
    public InetSocketAddress lookupService(String serviceName) {
        try {
            //获得提供某个服务的所有提供者的列表
            List<Instance> instances =  namingService.getAllInstances(serviceName);
            //这里为什么要get0
            //通过 getAllInstance 获取到某个服务的所有提供者列表后,需要选择一个,这里就涉及了负载均衡策略,这里我们先选择第 0 个,后面某节会详细讲解负载均衡。
            Instance instance = instances.get(0);
            return new InetSocketAddress(instance.getIp(), instance.getPort());
        } catch (NacosException e) {
            logger.error("获取服务时有错误发生:", e);
        }
        return null;
    }
}


三、服务注册发现

1.RpcServer新增 publishService方法,用于向 Nacos 注册服务

<T> void publishService(Object service, Class<T> serviceClass);

2.NettyServer 的实现

将服务保存在本地的注册表,同时注册到 Nacos 上

    @Override
    public <T> void publishService(Object service, Class<T> serviceClass) {
        serviceProvider.addService(service);
        serviceRegistry.register(serviceClass.getCanonicalName(), new InetSocketAddress(host, port));
        start();
    }

3.NettyClient修改

在sendrequest方法中首先从 ServiceRegistry 中获取到服务的地址和端口,再构造

   InetSocketAddress inetSocketAddress = serviceRegistry.lookupService(rpcRequest.getInterfaceName());
            Channel channel = ChannelProvider.get(inetSocketAddress);

四、测试

1.NettyTestClient

/**
 * 测试用Netty消费者
 * @author bdy
 */
public class NettyTestClient {
    public static void main(String[] args) {
        RpcClient client = new NettyClient();
//        client.setSerializer(new ProtobufSerializer());
        RpcClientProxy rpcClientProxy = new RpcClientProxy(client);
        HelloService helloService = rpcClientProxy.getProxy(HelloService.class);
        HelloObject object = new HelloObject(12, "This is a message");
        String res = helloService.hello(object);
        System.out.println(res);
    }
}

2.NettyTestServer

/**
 * 测试用Netty服务提供者(服务端)
 * @author bdy
 */
public class NettyTestServer {
    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        NettyServer server = new NettyServer("127.0.0.1", 9999);
//        server.setSerializer(new ProtobufSerializer());
        server.publishService(helloService, HelloService.class);
    }
}



总结

1.实现nacos注册中心

2.关于netty的编码解码器实现:
因为要传输的是自定义实体类,所以需要有编码解码器

                          pipeline.addLast(new ObjectDecoder(1024*1024, ClassResolvers.cacheDisabled((this.getClass().getClassLoader()))));
                          pipeline.addLast(new ObjectEncoder());

3.在NettyClient中可以不需要添加编解码器
原因:
在NettyClient中的bootstrap无用,主要是在ChannelProvider中实现bootstrap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值