JSON-RPC輕量級遠程調用協議介紹及使用

1、rpc知識

一、概念java

rpc:(Remote Procedure Call)遠程過程調用,是一個計算機通訊協議的泛稱。該協議容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而程序員無需額外地爲這個交互做用編程。若是涉及的軟件採用面向對象編程,那麼遠程過程調用亦可稱做遠程調用或遠程方法調用。git

遠程過程調用是一個分佈式計算的客戶端-服務器(Client/Server)的例子,它簡單而又廣受歡迎。遠程過程調用老是由客戶端對服務器發出一個執行若干過程請求,並用客戶端提供的參數。執行結果將返回給客戶端。因爲存在各式各樣的變體和細節差別,對應地派生了各式遠程過程調用協議,並且它們並不互相兼容。程序員

從通訊協議的層面,大體能夠分爲:github

基於HTTP協議的(例如基於文本的SOAP(XML)、Rest(JSON),基於二進制Hessian(Binary))web

基於TCP協議的(一般會藉助Mina、Netty等高性能網絡框架)spring

從不一樣的開發語言和平臺層面,分爲:數據庫

單種語言或平臺特定支持的通訊技術(例如Java平臺的RMI、.NET平臺Remoting)編程

支持跨平臺通訊的技術(例如HTTP Rest、Thrift等)json

從調用過程來看,分爲:服務器

同步通訊調用(同步RPC)

異步通訊調用(MQ、異步RPC)

常見的幾種通訊方式

1. 遠程數據共享(例如:共享遠程文件,共享數據庫等實現不一樣系統通訊)

2. 消息隊列

3. RPC(遠程過程調用)

序列化/反序列化

只有二進制數據才能在網絡中傳輸,序列化和反序列化的定義是:

將對象轉換成二進制流的過程叫作序列化,

將二進制流轉換成對象的過程叫作反序列化

2、json-rpc技術簡單介紹

json-rpc是基於json的跨語言遠程調用協議。比xml-rpc、webservice等基於文本的協議數據傳輸格式;相比於hessian、java-rpc等二進制協議更便於調試、實現、擴展,是很優秀的一種遠程調用協議。眼下主流語言都已有json-rpc的實現框架,java語言中較好的json-rpc實現框架有jsonrpc4j、jpoxy、json-rpc。三者之中jsonrpc4j既可獨立使用。又可與spring無縫集合,比較適合於基於spring的項目開發。

總結下,jsonrpc4j主要優勢有:

  • 代碼編寫簡單
  • 體積小巧
  • 與Spring完美整合

一、JSON-RPC協議描寫敘述
json-rpc協議很easy,發起遠程調用時向服務端數據傳輸格式例如如下:

{ "method": "sayHello", "params": ["Hello JSON-RPC"], "id": 1}

參數說明:
method: 調用的方法名
params: 方法傳入的參數。若無參數則傳入 []
id : 調用標識符。用於標示一次遠程調用過程
server其收到調用請求,處理方法調用,將方法效用結果效應給調用方;返回數據格式:

{   
    "result":          "Hello JSON-RPC",         
    "error":                null,       
      "id":                      1
 }

參數說明:
result: 方法返回值。若無返回值。則返回null。
若調用錯誤,返回null。
error :調用時錯誤,無錯誤返回null。
id : 調用標識符,與調用方傳入的標識符一致。
以上就是json-rpc協議規範,很easy,小巧。便於各類語言實現。

3、搭建服務端

添加依賴

<dependency>
    <groupId>com.github.briandilley.jsonrpc4j</groupId>
    <artifactId>jsonrpc4j</artifactId>
    <version>1.5.3</version>
</dependency>

添加配置類JsonRpcConfig

@Configuration
public class JsonRpcConfig {
    @Bean
    public AutoJsonRpcServiceImplExporter rpcServiceImplExporter(){
        return new AutoJsonRpcServiceImplExporter();
    }

添加JsonRpc服務接口

@JsonRpcService("rpc/products")
public interface ProductJsonRpcService {
    List<Product> findAll(ProductParam param);
    Product findOne(String id);
}

添加JsonRpc服務接口實現類

@AutoJsonRpcServiceImpl
@Service
public class ProductJsonRpcServiceImpl implements ProductJsonRpcService {
    @Autowired
    private ProductService productService;
    @Override
    public List<Product> findAll(ProductParam param) {
        Pageable pageable = PageRequest.of(0,100, Sort.Direction.DESC,"rewardRate");
        Page<Product> result = productService.query(param.getIdsList(),param.getNamesList(), param.getMinRewardRate(),
                param.getMaxRewardRate(), param.getStatusList(), pageable);
        return result.getContent();
    }
    @Override
    public Product findOne(String id) {
        productService.findById(id);
        return null;
    }
}

常見錯誤:
@JsonRpcService("rpc/products") 是正確的,須要注意的是這裏不能以/開始,例如/products就是錯誤的。

4、搭建客戶端

添加依賴

<dependency>
    <groupId>com.github.briandilley.jsonrpc4j</groupId>
    <artifactId>jsonrpc4j</artifactId>
    <version>1.5.3</version>
</dependency>

配置文件

rpc:
  client:
    url: http://localhost:8080/manager/         #1
    basePackage: com.momo.seller                #2

一、請求的服務端地址
二、rpc調用接口的包名,讓配置類去掃描

配置類

@Configuration
public class JsonRpcConfig {
    private static Logger LOG = LoggerFactory.getLogger(JsonRpcConfig.class);
    @Bean
    @ConditionalOnProperty(value = {"rpc.client.url","rpc.client.basePackage"})
    public AutoJsonRpcClientProxyCreator rpcClientProxyCreator(@Value("${rpc.client.url}") String url, @Value("${rpc.client.basePackage}") String basePackage) {
        AutoJsonRpcClientProxyCreator creator = new AutoJsonRpcClientProxyCreator();
        try {
            creator.setBaseUrl(new URL(url));
        } catch (MalformedURLException e) {
            LOG.error("建立rpc服務地址錯誤", e);
        }
        creator.setScanPackage(basePackage);
        return creator;
    }
}

客戶端接口

@JsonRpcService("rpc/products")
public interface ProductJsonRpcClient {
    List<Product> findAll(ProductParam param);
    Product findOne(String id);
}

測試

@RestController
@RequestMapping("/product")
public class ProductController {
    @Autowired
    ProductJsonRpcClient jsonRpcClient;
    @GetMapping("/{id}")
    public Product findOne(@PathVariable String id) {
        return jsonRpcClient.findOne(id);
    }
}

clipboard.png
成功調取服務端的內容,測試成功。。。。。

總結

json-rpc調用原理:
根據咱們配置的信息去掃描RPC的服務接口,而後去建立代理,執行的時候就是把咱們的操做信息轉化成json字符串的格式傳遞到服務端,而後服務端使用json字符串的形式返回來。
另外,其實服務端和客戶端的實體類和RPC接口代碼上是重複的,能夠分別獨立抽取出來做爲單獨的模塊,能夠減小代碼的重複。

相關文章
相關標籤/搜索