1. 程式人生 > >自己動手實現RPC

自己動手實現RPC

一、需求:使用者管理系統(UMS),倉庫管理系統(WMS),訂單管理系統(OMS)

現在OMS有一張訂單表:【訂單id,使用者id,商品id,訂單狀態,訂單時間】,需要在客戶端展示此訂單對應的使用者詳情和商品詳情

二、介面API整理:在OMS中,需要根據使用者id在UMS中查詢使用者詳情和根據商品id在WMS中查詢商品詳情

1.User selectUserById(long id)

2.Product selectProductById(long id)

三、介面呼叫架構圖:

四、程式碼實現

 1.工程結構

2.程式碼實現

// OMS系統程式碼
public
class Order {
private Long id; // 商品id private Long productId; // 使用者id private Long userId; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProductId() { return productId; } public void setProductId(Long productId) {
this.productId = productId; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } @Override public String toString() { return "Order{" + "id=" + id + ", productId=" + productId + ", userId=" + userId + '}'; } }
public class OrderService { public Order selectOrderById(long id){ Order order = new Order(); order.setId(id); order.setUserId(1l); order.setProductId(1L); return order; } } public class Main { public static void main(String[] args) { // 獲取訂單詳情 OrderService orderService = new OrderService(); Order order = orderService.selectOrderById(1L); System.out.println("訂單資訊:" + order); // 根據商品id獲取商品 ProductService productService = (ProductService) rpcHandle(ProductService.class, "127.0.0.1", 8888); Product product = productService.selectProductById(order.getProductId()); System.out.println("商品資訊:" + product); // 根據使用者id獲取使用者 UserService userService = (UserService) rpcHandle(UserService.class, "127.0.0.1", 9999); User user = userService.selectUserById(order.getUserId()); System.out.println("使用者資訊:" + user); } /** * RPC遠端呼叫實現 */ public static Object rpcHandle(final Class clazz, final String host, final int port) { return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket(host, port); // 想要呼叫遠端類的某個方法,必須要知道類名稱,方法名稱,引數型別,引數 String apiClassName = clazz.getName(); String methodName = method.getName(); Class[] parameterTypes = method.getParameterTypes(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeUTF(apiClassName); objectOutputStream.writeUTF(methodName); objectOutputStream.writeObject(parameterTypes); objectOutputStream.writeObject(args); objectOutputStream.flush(); ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); Object object = objectInputStream.readObject(); if (null != objectInputStream ){ objectInputStream.close(); } if (null != objectOutputStream){ objectOutputStream.close(); } if (null != socket){ socket.close(); } return object; } } ); } }
// WMS程式碼
public class Product implements Serializable {
    private Long id;
    private String name;
    private Double price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

public interface ProductService {

    /**
     * 根據商品ID查詢商品資訊
     *
     * @param id:商品id
     * @return
     */
    Product selectProductById(long id);
}

public class ProductServiceImpl implements ProductService {
    public Product selectProductById(long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("CAMEL運動鞋");
        product.setPrice(299.0);
        return product;
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            while (true) {
                Socket socket = serverSocket.accept();
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                // 讀取網路協議
                String apiClassName = objectInputStream.readUTF();
                String methodName = objectInputStream.readUTF();
                Class[] parameterTypes = (Class[]) objectInputStream.readObject();
                Object[] argsMethod = (Object[]) objectInputStream.readObject();

                Class clazz = null;
                // 服務註冊:API到具體實現的對映關係
                if (apiClassName.equals(ProductService.class.getName())) {
                    clazz = ProductServiceImpl.class;
                }
                ObjectOutputStream objectOutputStream = null;
                if (null != clazz) {
                    Method method = clazz.getMethod(methodName, parameterTypes);
                    Object invoke = method.invoke(clazz.newInstance(), argsMethod);
                    objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                    objectOutputStream.writeObject(invoke);
                    objectOutputStream.flush();
                }
                // 關閉資源
                if (null != objectInputStream) {
                    objectInputStream.close();
                }
                if (null != objectOutputStream) {
                    objectOutputStream.close();
                }
                if (null != socket) {
                    socket.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
// UUMS程式碼
public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

public interface UserService {

    /**
     * 根據使用者id,查詢使用者
     * @param id:使用者id
     * @return
     */
    User selectUserById(Long id);
}

public class UserServiceImpl implements UserService {
    public User selectUserById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("Jack Tang");
        user.setAge(20);
        return user;
    }
}

public class UserServiceImpl implements UserService {
    public User selectUserById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("Jack Tang");
        user.setAge(20);
        return user;
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            while (true) {
                Socket socket = serverSocket.accept();
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                String apiClassName = objectInputStream.readUTF();
                String methodName = objectInputStream.readUTF();
                Class[] parameterTypes = (Class[]) objectInputStream.readObject();
                Object[] argsMethod = (Object[]) objectInputStream.readObject();

                Class clazz = null;
                if (apiClassName.equals(UserService.class.getName())){
                    clazz = UserServiceImpl.class;
                }
                ObjectOutputStream objectOutputStream = null;
                if (null != clazz) {
                    Method method = clazz.getMethod(methodName, parameterTypes);
                    Object invoke = method.invoke(clazz.newInstance(), argsMethod);
                    objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                    objectOutputStream.writeObject(invoke);
                    objectOutputStream.flush();
                }
                // 關閉資源
                if (null != objectInputStream) {
                    objectInputStream.close();
                }
                if (null != objectOutputStream) {
                    objectOutputStream.close();
                }
                if (null != socket) {
                    socket.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

相關推薦

NET Core微服務之路:自己動手實現Rpc服務框架,基於DotEasy.Rpc服務框架的介紹和整合

本篇內容屬於非實用性(拿來即用)介紹,如對框架設計沒興趣的朋友,請略過。   快一個月沒有寫博文了,最近忙著兩件事;    一:閱讀劉墉先生的《說話的魅力》,以一種微妙的,你我大家都會經常遇見的事物,來建議說話的“藝術和魅力”,對於我們從事軟體開發、不太善於溝通

NET Core微服務之路:自己動手實現Rpc服務框架,基於DotEasy.Rpc服務框架的介紹和整合...

本篇內容屬於非實用性(拿來即用)介紹,如對框架設計沒興趣的朋友,請略過。  快一個月沒有寫博文了,最近忙著兩件事;    一:閱讀劉墉先生的《說話的魅力》,以一種微妙的,你我大家都會經常遇見的事物,來建議說話的“藝術和魅力”,對於我們從事軟體開發、不太善

自己動手實現RPC

一、需求:使用者管理系統(UMS),倉庫管理系統(WMS),訂單管理系統(OMS) 現在OMS有一張訂單表:【訂單id,使用者id,商品id,訂單狀態,訂單時間】,需要在客戶端展示此訂單對應的使用者詳情和商品詳情 二、介面API整理:在OMS中,需要根據使用者id在UMS中查詢使用者詳情和根據商品id在WMS

自己動手實現簡單權限控制

saweb 權限控制,很多項目會引入 shiro/spring-security。 shiro/spring-security 繼承 servlet-->filter抽象接口,運用合適的設計模式, 通過攔截客戶端請求,來實現各個角色對系統資源的訪問權限。 一時興起,有了自己實現權限控制的想法

自己動手實現瀏覽器,21天自制chromium:起手篇

發展 soci original tps 方案 ive ejs 系列 kit 轉:https://zhuanlan.zhihu.com/p/29101613?utm_medium=social&utm_source=qq 大家好,我又來了。這篇是21天自制原子彈的

自己動手實現一個簡單的JSON解析器

pair bool 優點 輕量 結束 pan isdigit 復雜 false 1. 背景 JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。相對於另一種數據交換格式 XML,JSON 有著諸多優點。比如易讀性更好,占用空間更少等

自己動手實現Epoll

epoll線程安全 rbtree smp epoll設計與實現 lt與et Epoll是Linux IO多路復用的管理機制。作為現在Linux平臺高性能網絡IO必要的組件。內核的實現可以參照:fs/eventpoll.c .為什麽需要自己實現epoll呢?現在自己打算做一個用戶態的協議棧

【原創】自己動手實現牛逼的單例模式

pre adr 關鍵字 LV trace ack 也會 code exceptio 引言 其實寫這篇文章之前,我猶豫了一下,畢竟單例大家都知道,寫這麽一篇文章會不會讓人覺得老掉牙。後來想想,就當一種記錄吧。先來一副漫畫吧,如下圖所示 ok,我們回顧下小灰的遭遇,上述漫畫所

手摸手教你自己動手實現一個前端路由

前言 用過現代前端框架的同學,對前端路由一定不陌生, vue, react, angular 都有自己的 router, 那麼你對 router 的工作原理了解嗎? 如果還不瞭解, 那麼請跟我一起來手寫一個簡單的前端路由, 順便了解一下. 實現路由的2種方式 hash模式

自己動手實現一個前端路由

單頁面應用利用了JavaScript動態變換網頁內容,避免了頁面過載,提供了流暢的使用者體驗;路由則提供了瀏覽器地址變化,網頁內容也跟隨變化,兩者結合起來則為我們提供了體驗良好的單頁面web應用 前端路由實現方式 前端路由需要實現三個功能:①瀏覽器地址變化,切換頁面;②點選瀏覽器【後退】、【前進

自己動手實現html5視訊播放器倍數播放功能

自己動手實現html5視訊播放器倍數播放功能 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>阿酷TONY--Tangni&

Atitit 學習一項技術的方法總結 目錄 1. 自己動手實現學習法 1 2. 七步學習法 —— 如何高效學習一項技能 1 3. 如何快速學習一項技能-十步學習法 - HugoLester - 部落格

Atitit 學習一項技術的方法總結   目錄 1. 自己動手實現學習法 1 2. 七步學習法 —— 如何高效學習一項技能 1 3. 如何快速學習一項技能-十步學習法 - HugoLester - 部落格園.html 2    

自己動手實現java資料結構(一) 向量

1.向量介紹   計算機程式主要執行在記憶體中,而記憶體在邏輯上可以被看做是連續的地址。為了充分利用這一特性,在主流的程式語言中都存在一種底層的被稱為陣列(Array)的資料結構與之對應。在使用陣列時需要事先宣告固定的大小以便程式在執行時為其開闢記憶體空間;陣列通過下標值計算出地址偏移量來對內部元素進行訪問

自己動手實現java數據結構(一) 向量

註意 api接口 復雜度 郵箱 ++ pri ont ren new 1.向量介紹 計算機程序主要運行在內存中,而內存在邏輯上可以被看做是連續的地址。為了充分利用這一特性,在主流的編程語言中都存在一種底層的被稱為數組(Array)的數據結構與之對應。在使用數組時需要事先聲明

自己動手實現java資料結構(二) 連結串列

1.連結串列介紹   前面我們已經介紹了向量,向量是基於陣列進行資料儲存的線性表。今天,要介紹的是線性表的另一種實現方式---連結串列。   連結串列和向量都是線性表,從使用者的角度上依然被視為一個線性的列表結構。但是,連結串列內部儲存資料的方式卻和向量大不相同:連結串列的核心是節點。節點儲存"資料"的同

自己動手實現神經網路分詞模型

本文由**羅周楊[email protected]**原創,轉載請註明原作者和出處。 原文連結:luozhouyang.github.io/deepseg 分詞作為NLP的基礎工作之一,對模型的效果有直接的影響。一個效果好的分詞,可以讓模型的效能更好。 在嘗試使用神經網路來分詞之前,

自己動手實現一個簡單的Mybatis(初級版本1.0)

手寫Mybatis-v1.0 原始碼連結(包括v1.0與v2.0): https://github.com/staticLin/customMyBatis.git 從上一個文章 ---Mybatis概述中瞭解到了Mybatis的主要架構與底層原理流程,結尾給出了一個巨集觀流程圖,可

自己動手實現java資料結構(三) 棧

自己動手實現java資料結構(三) 棧 1.棧的介紹   在許多演算法設計中都需要一種"先進後出(First Input Last Output)"的資料結構,因而一種被稱為"棧"的資料結構被抽象了出來。   棧的結構類似一個罐頭:只有一個開口;先被放進去的東西沉在底下,後放進去的東西被

自己動手實現html去標籤和文字提取

原文出處:https://blog.csdn.net/AsuraDong/article/details/72877382 隨意觀看 工具準備 全形和半形字元 網頁字元實體 Code實現 之後... 工具準備 python3.

自己動手實現資料結構模板(1):雙向連結串列

今天忽然心血來潮,自己動手實現了一個簡單的雙向連結串列和基本功能,大致實現瞭如下功能 dtsListNode為結點類,包括值value、前向指標pre和後向指標next。 dtsList為雙向連結串列,能夠通過begin和end函式獲得首地址指標和指向最後一