在 Linux 上实现 Java 应用的负载均衡
一、方案总览与选型
二、使用 Nginx 或 HAProxy 的反向代理方案
http {
upstream backend {
server 192.168.1.11:8080;
server 192.168.1.12:8080;
server 192.168.1.13:8080;
}
server {
listen 80;
server_name your.domain.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
三、Java 微服务内建负载均衡
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 如需服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://eureka1:8761/eureka,http://eureka2:8761/eureka
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
调用时使用服务名:restTemplate.getForObject(“http://product-service/api/items”, String.class);四、自研简易 Java 负载均衡器(学习/内网工具)
public class LoadBalancer {
private final List<Server> servers = new ArrayList<>();
private final AtomicInteger idx = new AtomicInteger(0);
public void addServer(Server s) { servers.add(s); }
public void removeServer(Server s) { servers.remove(s); }
public Server getNextServer() {
if (servers.isEmpty()) throw new IllegalStateException("No servers");
// 简单轮询
return servers.get(Math.abs(idx.getAndIncrement()) % servers.size());
}
}
class Server { String host; int port; /* 健康探测、权重等 */ }
五、生产实践与运维要点