基于网络的通信

共享内存

消息中间件

进程间管道

文件系统

远程过程调用(RPC)

HTTP/REST API

分布式缓存(如Redis、Memcached)

基于网络的通信

TCP:

通过网络协议(TCP)建立连接,允许进程间通过IP地址和端口进行通信。适用于本地或远程进程间通信,支持跨平台。

  • TCP服务器端:

    ServerSocket serverSocket = new ServerSocket(8080);
    Socket clientSocket = serverSocket.accept();
    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    String message = in.readLine();
    out.println("收到消息:" + message);
    
  • TCP客户端

    Socket socket = new Socket("localhost", 8080);
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out.println("Hello IPC!");
    String response = in.readLine();
    System.out.println("服务器回复:" + response);
    
  • 优缺点

    • 优点:跨平台、灵活、支持远距离通信。
    • 缺点:需要处理网络延迟、连接管理,且没有内置的序列化支持。

UDP:

通过UDP多播协议向一组进程发送消息,适合广播场景

  • 多播服务器端:

    MulticastSocket socket = new MulticastSocket(4446);
    InetAddress group = InetAddress.getByName("230.0.0.1");
    socket.joinGroup(group);
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    socket.receive(packet);
    String message = new String(packet.getData(), 0, packet.getLength());
    System.out.println("收到消息:" + message);
    
  • 多播客户端

    MulticastSocket socket = new MulticastSocket();
    InetAddress group = InetAddress.getByName("230.0.0.1");
    socket.send(new DatagramPacket("Multicast消息".getBytes(), "Multicast消息".length(), group, 4446));
    
  • 优缺点

    • 优点:适合广播式通信,无需建立连接。
    • 缺点:无可靠传输保证(UDP),需自己处理数据丢失。

共享内存

内存映射文件:

通过FileChannel的map()方法将文件映射到内存,多个进程可读写同一文件实现共享。

  • 优缺点
    • 优点:高效,适合大量数据传输。
    • 缺点:需手动处理同步问题,依赖文件系统,跨平台兼容性有限
// 写入端
FileChannel channel = FileChannel.open(Paths.get("shared.dat"), StandardOpenOption.READ, StandardOpenOption.WRITE);
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
buffer.put("共享内存数据".getBytes());

// 读取端
FileChannel channel = FileChannel.open(Paths.get("shared.dat"), StandardOpenOption.READ);
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, 1024);
String data = new String(buffer.array());
System.out.println("读取到数据:" + data);

共享内存库:

通过本地库(如POSIX共享内存)实现更直接的内存共享。但是开发复杂,跨平台支持差。

消息中间件

JMS(Java Message Service):

基于消息队列的标准接口,支持多种消息模式(点对点、发布-订阅)

  • 优缺点
    • 优点:可靠的异步通信,支持持久化。
    • 缺点:需要依赖消息中间件服务(如ActiveMQ、RabbitMQ)。

Redis:

利用Redis的发布-订阅或键值存储功能传递消息。

// 发布消息
Jedis jedis = new Jedis("localhost");
jedis.publish("channel:ipc", "Redis消息");

// 订阅消息
jedis.subscribe(new JedisPubSub() {
  @Override
  public void onMessage(String channel, String message) {
    System.out.println("收到消息:" + message);
  }
}, "channel:ipc");
  • 优缺点
    • 优点:分布式支持,灵活的消息模式。
    • 缺点:需要依赖Redis服务。

进程间管道

匿名管道(Anonymous Pipe):

通过ProcessBuilder启动子进程,使用输入/输出流通信。

  • 优缺点
    • 优点:简单易用,适合父子进程通信。
    • 缺点:仅限有亲缘关系的进程,且单向通信。
// 父进程
ProcessBuilder pb = new ProcessBuilder("java", "ChildProcess");
Process child = pb.start();
OutputStream os = child.getOutputStream();
os.write("父进程发送的消息".getBytes());
os.flush();

// 子进程(ChildProcess类)
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String message = reader.readLine();
System.out.println("子进程收到:" + message);

命名管道(FIFO):

通过操作系统提供的命名管道文件实现无亲缘关系进程通信。

  • 实现方式(Linux/Unix):

    mkfifo /tmp/ipc.fifo  # 创建命名管道文件
    
  • 写入端

    FileOutputStream out = new FileOutputStream("/tmp/ipc.fifo");
    out.write("FIFO消息".getBytes());
    
  • 读取端:

    FileInputStream in = new FileInputStream("/tmp/ipc.fifo");
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String message = reader.readLine();
    
  • 优缺点

    • 优点:本地高效,无需网络。
    • 缺点:依赖操作系统,需处理阻塞问题。

文件系统

共享文件

多个进程读写同一文件,需自行处理数据同步和锁机制。

// 写入数据
try (FileWriter writer = new FileWriter("shared.txt", true)) {
  writer.write("新数据\n");
}

// 读取数据
try (FileReader reader = new FileReader("shared.txt")) {
  int i;
  while ((i = reader.read()) != -1) {
    System.out.print((char) i);
  }
}
  • 优缺点
    • 优点:简单,无需额外组件。
    • 缺点:效率低,同步困难,易引发竞争条件。

数据库表

多个进程通过共享数据库表交换数据(如MySQL、PostgreSQL)。

// 写入数据
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db", "user", "pass");
PreparedStatement stmt = conn.prepareStatement("INSERT INTO messages (content) VALUES (?)");
stmt.setString(1, "数据库消息");
stmt.executeUpdate();

// 读取数据
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM messages");
while (rs.next()) {
  System.out.println("消息内容:" + rs.getString("content"));
}
  • 优缺点
    • 优点:支持事务和持久化。
    • 缺点:性能开销较大,适合数据量不大的场景。

远程过程调用(RPC)

RMI(Remote Method Invocation)

通过远程对象调用实现请求-响应模式,进程间可像调用本地方法一样交互

  • 实现步骤

    1. 定义远程接口并实现。
    2. 启动RMI注册中心。
    3. 绑定远程对象到注册中心。
    4. 客户端查找并调用对象。
  • 远程接口:

    public interface Calculator extends Remote {
      int add(int a, int b) throws RemoteException;
    }
    
  • 服务端:

    CalculatorImpl calc = new CalculatorImpl();
    LocateRegistry.createRegistry(1099);
    Naming.bind("rmi://localhost:1099/Calculator", calc);
    
  • 客户端:

    Calculator calc = (Calculator) Naming.lookup("rmi://localhost:1099/Calculator");
    System.out.println("结果:" + calc.add(3, 5));
    
  • 优缺点

    • 优点:直观易用,支持跨进程和跨网络。
    • 缺点:配置复杂,性能较低,需处理序列化兼容性。

HTTP/REST API

通过HTTP协议发送请求和接收响应,适合微服务架构。使用Spring Boot:

  • 服务端
@RestController
public class ServerController {
  @GetMapping("/add")
  public int add(@RequestParam int a, @RequestParam int b) {
    return a + b;
  }
}
  • 客户端(使用HttpClient)
  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://localhost:8080/add?a=3&b=5"))
    .build();
  HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

分布式缓存(如Redis、Memcached)

通过缓存服务器存储和获取数据,实现进程间共享。

Redis的键值通信

// 写入缓存
Jedis jedis = new Jedis("localhost");
jedis.set("key", "value");

// 读取缓存
String value = jedis.get("key");
System.out.println("读取到:" + value);

利用restTemplate

使用restTemplate调用远程服务的URL,也可实现不同进程间的调用

  • SpringBoot中注入restTemplate

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
  • 调用exchange()方法

    restTemplate.exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType)
    
    • URI url:访问的URL

    • HttpMethod method:http请求的方法;

    • @Nullable HttpEntity<?> requestEntity:请求实例

      • 可添加请求头和请求体

        HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers)
        

        请求头中可增加身份验证的token;

    • Class responseType:返回对象类型;

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐