分布式架构网络通信

在分布式系统设计中,网络通信是最基础也是最重要的组成部分。在Java生态系统中,有多种技术可以实现远程服务通信:

  1. RMI (Remote Method Invocation):Java原生的远程调用框架
  2. Hessian:基于HTTP的轻量级RPC框架
  3. SOAP:基于XML的Web服务协议
  4. ESB (Enterprise Service Bus):企业服务总线
  5. JMS (Java Message Service):面向消息的中间件API

基本原理

网络通信基础

从计算机系统底层来看,网络通信的本质是将数据从一台计算机传输到另一台计算机。这个过程主要涉及两个关键组件:

  1. 传输协议

    • TCP:面向连接的可靠传输协议,提供数据顺序保证和重传机制
    • UDP:无连接的不可靠传输协议,提供较低的延迟
  2. 网络IO模型

    • BIO (Blocking IO):同步阻塞模型
    • NIO (Non-blocking IO):同步非阻塞模型
    • AIO (Asynchronous IO):异步非阻塞模型

开发流程

服务端开发步骤

  1. 定义远程接口:创建一个继承自java.rmi.Remote的子接口
  2. 实现远程接口:创建一个实现类,继承java.rmi.server.UnicastRemoteObject
  3. 启动RMI服务器:创建注册表并绑定远程对象

客户端开发步骤

  1. 查找远程对象:使用Naming.lookup()方法获取远程对象的Stub
  2. 调用远程方法:调用方法与本地方法调用语法相同

代码实现

创建远程接口

package icu.wzk.service;

import icu.wzk.model.WzkUser;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface WzkService extends Remote {
    String sayHello(WzkUser wzkUser) throws RemoteException;
}

创建引用对象

package icu.wzk.model;

public class WzkUser implements Serializable {
    private String name;
    private int age;
    // 省略 get 和 set 方法
}

实现远程服务对象

package icu.wzk.service.impl;

import icu.wzk.model.WzkUser;
import icu.wzk.service.WzkService;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class WzkServiceImpl extends UnicastRemoteObject implements WzkService {
    private static final long serialVersionUID = 1L;

    public WzkServiceImpl() throws RemoteException {
        super();
    }

    @Override
    public String sayHello(WzkUser wzkUser) throws RemoteException {
        System.out.println("WzkService: " + wzkUser.getName() + ", " + wzkUser.getAge());
        return "success";
    }
}

服务端程序

package icu.wzk;

import icu.wzk.service.WzkService;
import icu.wzk.service.impl.WzkServiceImpl;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class WzkServer {
    public static void main(String[] args) throws Exception {
        WzkService wzkService = new WzkServiceImpl();
        LocateRegistry.createRegistry(8888);
        Naming.bind("//127.0.0.1:8888/wzk", wzkService);
    }
}

客户端程序

package icu.wzk;

import icu.wzk.model.WzkUser;
import icu.wzk.service.WzkService;
import java.rmi.Naming;

public class WzkClient {
    public static void main(String[] args) throws Exception {
        WzkService wzkService = (WzkService) Naming.lookup("//127.0.0.1:8888/wzk");
        WzkUser wzkUser = new WzkUser();
        wzkUser.setAge(18);
        wzkUser.setName("wzkicu");
        System.out.println(wzkService.sayHello(wzkUser));
    }
}

测试效果

运行 WzkServer 和 WzkClient 程序后:

  • 客户端返回结果:success
  • 服务端输出:WzkService: wzkicu, 18