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

基于Socket+Zookeeper的简单RPC框架

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

github:https://github.com/shawntime/shawn-native-rpc

RPC过程详解

image.png

image.png

实现内容

  • json序列化
  • zookeeper实现服务端服务注册和客户端的服务发现和负载均衡
  • 自动扫描服务端所提供的接口,并注册到zookeeper中
  • 自动生成客户端动态代理对象
  • socket实现通讯

模块说明

  • native-core:公共包:注解、异常定义、通讯协议、序列化、zookeeper客户端封装以及包扫描,配置加载等工具类
  • native-customer:调用方需引入的模块,实现自动生成客户端动态代理对象,zk的服务发现和负载均衡,以及通信实现
  • native-provider:服务提供方需引入的模块,实现了接口客户端请求并处理,zk的服务注册
  • native-interface:对外提供服务的接口定义
  • shawn-test-provider:提供方demo
  • shawn-test-customer:调用方demo

配置

provider配置

配置naive-rpc.properties文件

scanPackage=com.shawntime.rpc.api
servicePort=11001
  • scanPackage: 包扫描路径,自动创建包路径下接口动态代理类
  • servicePort: 服务端监听端口号

配置spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd
       http://www.springframework.org/schema/cache
       http://www.springframework.org/schema/cache/spring-cache-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.shawntime"/>
    <context:annotation-config/>
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <!-- 配置消息格式化方式 -->
    <bean id="jsonFormatter" class="com.shawntime.rpc.core.serialize.json.JsonFormatter" />
    <bean id="jsonParse" class="com.shawntime.rpc.core.serialize.json.JsonParse" />

    <!-- 配置服务类,该处使用socket处理请求 -->
    <bean id="rpcProvider" class="com.shawntime.rpc.provider.service.socket.SocketRpcProvider">
        <property name="formatter" ref="jsonFormatter" />
        <property name="parse" ref="jsonParse" />
    </bean>

    <!-- 配置zk服务器集群信息,作服务注册 -->
    <bean id="zookeeperClient" class="com.shawntime.rpc.core.zookeeper.ZookeeperClient">
        <constructor-arg value="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183" />
    </bean>
</beans>
customer配置

配置naive-rpc.properties文件

scanPackage=com.shawntime.rpc.api
  • scanPackage: 包扫描路径,自动创建包路径下接口动态代理类

配置spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd
       http://www.springframework.org/schema/cache
       http://www.springframework.org/schema/cache/spring-cache-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.shawntime"/>
    <context:annotation-config/>
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <!-- 配置消息格式化方式 -->
    <bean id="jsonFormatter" class="com.shawntime.rpc.core.serialize.json.JsonFormatter" />
    <bean id="jsonParse" class="com.shawntime.rpc.core.serialize.json.JsonParse" />
    
    <!-- 客户端处理配置 -->
    <bean id="socketInvoke" class="com.shawntime.rpc.customer.invoke.socket.SocketInvoke" />
    
    <bean id="beanNameGenerator" class="org.springframework.context.annotation.AnnotationBeanNameGenerator" />

    <!-- 客户端动态代理注册类 -->
    <bean id="customBeanDefinitionRegistryPostProcessor"
          class="com.shawntime.rpc.customer.config.CustomBeanDefinitionRegistryPostProcessor">
        <property name="invoke" ref="socketInvoke" />
        <property name="formatter" ref="jsonFormatter" />
        <property name="parse" ref="jsonParse" />
        <property name="beanNameGenerator" ref="beanNameGenerator" />
        <property name="serviceFindManager" ref="serviceFindManager" />
    </bean>

    <!-- 服务发现和负载均衡 -->
    <bean id="serviceFindManager" class="com.shawntime.rpc.customer.ServiceFindManager">
        <property name="zookeeperClient" ref="zookeeperClient" />
    </bean>

    <!-- 配置zk服务器集群信息,作服务注册 -->
    <bean id="zookeeperClient" class="com.shawntime.rpc.core.zookeeper.ZookeeperClient">
        <constructor-arg value="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183" />
    </bean>
</beans>

Demo

  • 接口定义,用RpcService注解
@RpcService
public interface IUserService {

    UserOut getUserInfo(UserIn userIn, Integer level);

    void addUserProvince(ProvinceIn in);
}
  • 提供方
package com.shawntime.test.provider;

import com.shawntime.rpc.api.IUserService;
import com.shawntime.rpc.api.contract.ProvinceIn;
import com.shawntime.rpc.api.contract.UserIn;
import com.shawntime.rpc.api.contract.UserOut;
import org.springframework.stereotype.Component;

@Component
public class UserService implements IUserService {

    public UserOut getUserInfo(UserIn userIn, Integer level) {
        UserOut userOut = new UserOut();
        if (level > 0) {
            userOut.setUserId(1);
            userOut.setAddress("安徽芜湖");
            userOut.setAge(18);
            userOut.setUserName(userIn.getUserName());
        } else {
            userOut.setUserId(2);
            userOut.setAddress("河北保定");
            userOut.setAge(19);
            userOut.setUserName(userIn.getUserName());
        }
        return userOut;
    }

    public void addUserProvince(ProvinceIn provinceIn) {
        System.out.println(provinceIn);
    }
}

  • 调用方
@Component
public class LoginService implements ILoginService {

    @Resource
    private IUserService userService;

    public boolean login(String userName, String password, Integer level) {
        UserIn userIn = new UserIn();
        userIn.setUserName(userName);
        userIn.setPassword(password);
        UserOut userInfo = userService.getUserInfo(userIn, level);
        System.out.println("userId:" + userInfo.getUserId()
                + ", age:" + userInfo.getAge()
                + ", address:" + userInfo.getAddress());
        return userInfo != null;
    }

    public int addUserProvince(ProvinceIn in) {
        userService.addUserProvince(in);
        return 1;
    }
}

转载于:https://my.oschina.net/shma1664/blog/1626337

相关文章:

  • 算法学习之路|升序排序
  • vue:响应原理
  • yum.repos.d中的变量($releasever与$basearch)
  • Activiti6.0 java项目框架 spring5 SSM 工作流引擎 审批流程
  • 造成类在多线程时不安全的原因
  • JavaScript中的图片处理与合成(一)
  • 在 Laravel 中动态隐藏 API 字段
  • 采购与供应商管理:如何突破传统模式
  • GDB调试技巧:gdb at pid无法调试的问题
  • [CERC2017]Cumulative Code
  • 使用OpenCV+C++将Gif文件分解并且转换为视频文件
  • webTest-----webUI自动化框架
  • 高通无人机新技术,深度学习把控飞行安全
  • 比特币价格再创新高,当年的0.3美分已经变为7290万美元
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • [Vue CLI 3] 配置解析之 css.extract
  • Android系统模拟器绘制实现概述
  • Angular 4.x 动态创建组件
  • Solarized Scheme
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • Vue 重置组件到初始状态
  • Vue--数据传输
  • zookeeper系列(七)实战分布式命名服务
  • 电商搜索引擎的架构设计和性能优化
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 今年的LC3大会没了?
  • 入口文件开始,分析Vue源码实现
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 用Visual Studio开发以太坊智能合约
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 2017年360最后一道编程题
  • ​ssh免密码登录设置及问题总结
  • ​低代码平台的核心价值与优势
  • #1014 : Trie树
  • #Linux(权限管理)
  • #QT(串口助手-界面)
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • ( 10 )MySQL中的外键
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (HAL库版)freeRTOS移植STMF103
  • (LeetCode) T14. Longest Common Prefix
  • (九)信息融合方式简介
  • (实战篇)如何缓存数据
  • (小白学Java)Java简介和基本配置
  • (学习日记)2024.01.09
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • (轉)JSON.stringify 语法实例讲解
  • .NET Core 中的路径问题
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .net 流——流的类型体系简单介绍
  • .Net各种迷惑命名解释
  • .NET下ASPX编程的几个小问题
  • .NET中的Exception处理(C#)
  • .NET中两种OCR方式对比