本文目录导读:

- 简单HTTP反向代理(基于Socket)
- 使用Apache HttpClient的实现(功能更强大)
- 高性能反向代理(Netty实现)
- 使用Spring Cloud Gateway(微服务场景)
- Nginx反向代理配置(生产环境推荐)
- 配置文件和依赖
- 关键特性说明
- 使用场景
我来为您提供一个完整的Java反向代理实现案例,包含多种实现方式。
简单HTTP反向代理(基于Socket)
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.*;
import java.net.*;
import java.util.concurrent.Executors;
/**
* 简单的HTTP反向代理服务器
*/
public class SimpleReverseProxy {
public static void main(String[] args) throws IOException {
// 创建HTTP服务器监听8080端口
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
// 设置代理处理
server.createContext("/", new ProxyHandler());
server.setExecutor(Executors.newFixedThreadPool(10));
System.out.println("代理服务器启动在 8080 端口...");
server.start();
}
static class ProxyHandler implements HttpHandler {
// 目标服务器
private static final String TARGET_HOST = "example.com";
private static final int TARGET_PORT = 80;
@Override
public void handle(HttpExchange exchange) throws IOException {
// 构建目标URL
String path = exchange.getRequestURI().getPath();
String query = exchange.getRequestURI().getQuery();
String targetUrl = "http://" + TARGET_HOST + ":" + TARGET_PORT + path;
if (query != null && !query.isEmpty()) {
targetUrl += "?" + query;
}
try {
// 创建到目标服务器的连接
URL url = new URL(targetUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(exchange.getRequestMethod());
// 复制请求头
exchange.getRequestHeaders().forEach((key, values) -> {
values.forEach(value -> connection.setRequestProperty(key, value));
});
// 处理请求体
if (exchange.getRequestMethod().equals("POST") ||
exchange.getRequestMethod().equals("PUT")) {
connection.setDoOutput(true);
try (OutputStream outputStream = connection.getOutputStream();
InputStream inputStream = exchange.getRequestBody()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
}
// 获取响应
int responseCode = connection.getResponseCode();
// 设置响应头
exchange.getResponseHeaders().set("Content-Type",
connection.getContentType() != null ?
connection.getContentType() : "text/html");
// 发送响应
exchange.sendResponseHeaders(responseCode, 0);
// 复制响应体
try (InputStream inputStream = connection.getInputStream();
OutputStream outputStream = exchange.getResponseBody()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
} catch (Exception e) {
// 错误响应
String error = "代理错误: " + e.getMessage();
exchange.sendResponseHeaders(500, error.length());
try (OutputStream os = exchange.getResponseBody()) {
os.write(error.getBytes());
}
} finally {
exchange.close();
}
}
}
}
使用Apache HttpClient的实现(功能更强大)
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.net.URI;
/**
* 基于Servlet的HTTP反向代理
*/
public class ServletReverseProxy extends HttpServlet {
private final CloseableHttpClient httpClient;
private final String targetServer;
public ServletReverseProxy() {
// 初始化HTTP客户端
this.httpClient = HttpClients.createDefault();
// 目标服务器地址
this.targetServer = "http://backend-server:8081";
}
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// 构建目标URI
String targetPath = buildTargetPath(request);
String targetUrl = targetServer + targetPath;
try {
// 创建请求
HttpUriRequest proxyRequest = createRequest(request, targetUrl);
// 执行请求
try (CloseableHttpResponse proxyResponse =
httpClient.execute(proxyRequest)) {
// 复制响应头
response.setStatus(proxyResponse.getStatusLine().getStatusCode());
for (org.apache.http.Header header :
proxyResponse.getAllHeaders()) {
response.setHeader(header.getName(), header.getValue());
}
// 复制响应体
HttpEntity entity = proxyResponse.getEntity();
if (entity != null) {
response.getOutputStream().write(
EntityUtils.toByteArray(entity)
);
}
}
} catch (Exception e) {
response.setStatus(500);
response.getWriter().write("代理错误: " + e.getMessage());
}
}
private String buildTargetPath(HttpServletRequest request) {
String path = request.getRequestURI();
String query = request.getQueryString();
if (query != null && !query.isEmpty()) {
path += "?" + query;
}
return path;
}
private HttpUriRequest createRequest(HttpServletRequest request,
String targetUrl) {
String method = request.getMethod();
HttpUriRequest proxyRequest;
switch (method) {
case "POST":
HttpPost post = new HttpPost(targetUrl);
proxyRequest = post;
break;
case "PUT":
HttpPut put = new HttpPut(targetUrl);
proxyRequest = put;
break;
case "DELETE":
HttpDelete delete = new HttpDelete(targetUrl);
proxyRequest = delete;
break;
default:
HttpGet get = new HttpGet(targetUrl);
proxyRequest = get;
}
// 复制请求头
java.util.Enumeration<String> headerNames =
request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
proxyRequest.setHeader(headerName, headerValue);
}
return proxyRequest;
}
}
高性能反向代理(Netty实现)
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
/**
* Netty实现的高性能反向代理
*/
public class NettyReverseProxy {
public static void main(String[] args) throws InterruptedException {
// 创建事件循环组
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
EventLoopGroup targetGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new ProxyHandler(targetGroup, "backend-server", 8081));
}
});
// 启动服务器
Channel serverChannel = serverBootstrap.bind(8080).sync().channel();
System.out.println("Netty反向代理启动在 8080 端口");
serverChannel.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
targetGroup.shutdownGracefully();
}
}
static class ProxyHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private final EventLoopGroup targetGroup;
private final String targetHost;
private final int targetPort;
public ProxyHandler(EventLoopGroup targetGroup,
String targetHost, int targetPort) {
this.targetGroup = targetGroup;
this.targetHost = targetHost;
this.targetPort = targetPort;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx,
FullHttpRequest request) {
// 复制请求
FullHttpRequest proxiedRequest = request.copy();
// 创建到目标服务器的连接
Bootstrap bootstrap = new Bootstrap()
.group(targetGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpClientCodec());
ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new ResponseHandler(ctx));
}
});
// 连接到目标服务器并发送请求
bootstrap.connect(targetHost, targetPort).addListener(
(ChannelFuture future) -> {
if (future.isSuccess()) {
future.channel().writeAndFlush(proxiedRequest);
} else {
ctx.writeAndFlush(new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
HttpResponseStatus.BAD_GATEWAY
));
ctx.close();
}
}
);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
static class ResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
private final ChannelHandlerContext clientContext;
public ResponseHandler(ChannelHandlerContext clientContext) {
this.clientContext = clientContext;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx,
FullHttpResponse response) {
// 转发响应到客户端
clientContext.writeAndFlush(response.copy());
// 关闭连接
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
}
使用Spring Cloud Gateway(微服务场景)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
// 用户服务路由
.route("user-service", r -> r
.path("/api/user/**")
.filters(f -> f
.stripPrefix(2)
.addResponseHeader("X-Proxied-By", "Gateway")
.retry(3)
.circuitBreaker(c -> c
.setName("userServiceCB")
.setFallbackUri("forward:/fallback/user")))
.uri("http://localhost:8081/"))
// 订单服务路由
.route("order-service", r -> r
.path("/api/order/**")
.filters(f -> f
.stripPrefix(2)
.addRequestHeader("X-Trace-Id",
"trace-" + System.currentTimeMillis()))
.uri("http://localhost:8082/"))
// 负载均衡示例
.route("load-balanced", r -> r
.path("/api/load/**")
.uri("lb://LOAD-BALANCED-SERVICE"))
.build();
}
}
Nginx反向代理配置(生产环境推荐)
# nginx.conf
upstream backend_servers {
ip_hash; # 会话保持
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080 weight=2;
server backend3.example.com:8080 backup;
}
server {
listen 80;
server_name example.com;
# 基本反向代理
location /api/ {
proxy_pass http://backend_servers;
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;
}
# WebSocket代理
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 静态文件缓存
location /static/ {
proxy_pass http://static_servers;
proxy_cache static_cache;
proxy_cache_valid 200 304 1h;
expires 1h;
}
# 负载均衡
upstream websocket_backend {
least_conn; # 最少连接
server ws1.example.com:9090;
server ws2.example.com:9090;
}
}
配置文件和依赖
pom.xml依赖
<dependencies>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.75.Final</version>
</dependency>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.3</version>
</dependency>
</dependencies>
关键特性说明
- 请求转发:将客户端请求转发到后端服务器
- 响应缓存:缓存常用响应提高性能
- 负载均衡:分发请求到多个后端服务器
- URL重写:修改请求路径
- 安全过滤:添加认证、速率限制
- 日志记录:记录请求和响应信息
- 错误处理:处理后端故障和超时
- 协议转换:支持HTTP/HTTPS、WebSocket等
使用场景
- 微服务网关:统一入口,路由分发
- 负载均衡:分发流量到多个实例
- 安全防护:隐藏后端结构,添加认证
- 跨域处理:解决CORS问题
- 协议转换:HTTP转WebSocket等
- 流量控制:限流、熔断、重试
选择哪种实现方式取决于您的具体需求、性能要求和部署环境,对于生产环境,建议使用成熟的解决方案如Nginx或Spring Cloud Gateway。