From 121526578abbc3e4b4e416be6c01f84ba99fde77 Mon Sep 17 00:00:00 2001 From: zhoujian Date: Sun, 23 May 2021 23:33:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 02nio/nio02/pom.xml | 7 +++ .../main/java/com/jianjoy/http/HttpUtil.java | 51 +++++++++++++++++ .../com/jianjoy/http/SimpleHttpServer.java | 41 ++++++++++++++ .../gateway/NettyServerApplication.java | 21 ++++--- .../gateway/filter/MyHttpRequestFilter.java | 16 ++++++ .../gateway/filter/MyHttpResponseFilter.java | 20 +++++++ .../gateway/inbound/HttpInboundHandler.java | 35 ++++++++---- .../okhttp/OkHttpOutboundHandler.java | 56 +++++++++++++++++++ .../okhttp/OkhttpOutboundHandler.java | 4 -- .../gateway/router/MyEndpointRouter.java | 21 +++++++ 10 files changed, 249 insertions(+), 23 deletions(-) create mode 100644 02nio/nio02/src/main/java/com/jianjoy/http/HttpUtil.java create mode 100644 02nio/nio02/src/main/java/com/jianjoy/http/SimpleHttpServer.java create mode 100644 02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpRequestFilter.java create mode 100644 02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpResponseFilter.java create mode 100644 02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkHttpOutboundHandler.java delete mode 100644 02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkhttpOutboundHandler.java create mode 100644 02nio/nio02/src/main/java/io/github/kimmking/gateway/router/MyEndpointRouter.java diff --git a/02nio/nio02/pom.xml b/02nio/nio02/pom.xml index 005de90a..b8caaff1 100644 --- a/02nio/nio02/pom.xml +++ b/02nio/nio02/pom.xml @@ -56,6 +56,7 @@ org.projectlombok lombok + 1.14.8 + + com.squareup.okhttp + okhttp + 2.7.5 + + diff --git a/02nio/nio02/src/main/java/com/jianjoy/http/HttpUtil.java b/02nio/nio02/src/main/java/com/jianjoy/http/HttpUtil.java new file mode 100644 index 00000000..fb0c7f11 --- /dev/null +++ b/02nio/nio02/src/main/java/com/jianjoy/http/HttpUtil.java @@ -0,0 +1,51 @@ +package com.jianjoy.http; + +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * Author: zhoujian + * Description:http工具 + * Date: 2021/5/16 22:34 + */ +public final class HttpUtil { + + + private static final OkHttpClient CLIENT = new OkHttpClient(); + + private HttpUtil() { + + } + + static { + CLIENT.setConnectTimeout(30, TimeUnit.SECONDS); + CLIENT.setReadTimeout(30, TimeUnit.SECONDS); + } + + + /** + * 发送get请求获取返回内容 + * + * @param url + * @return + * @throws IOException + */ + public static String sendGet(String url) throws IOException { + Request request = new Request.Builder() + .url(url) + .build(); + Response response = CLIENT.newCall(request).execute(); + return response.body().string(); + } + + public static void main(String[] args) throws Exception { + SimpleHttpServer.main(args); + System.out.println(sendGet("http://localhost:8801")); + } + + +} diff --git a/02nio/nio02/src/main/java/com/jianjoy/http/SimpleHttpServer.java b/02nio/nio02/src/main/java/com/jianjoy/http/SimpleHttpServer.java new file mode 100644 index 00000000..a7802316 --- /dev/null +++ b/02nio/nio02/src/main/java/com/jianjoy/http/SimpleHttpServer.java @@ -0,0 +1,41 @@ +package com.jianjoy.http; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Date; + +/** + * Author: zhoujian + * Description:简单http server + * Date: 2021/5/16 22:48 + */ +public class SimpleHttpServer { + + + public static void main(String[] args) throws IOException { + createHttpServer(8801).start(); + createHttpServer(8802).start(); + System.out.println("SimpleHttpServer started."); + } + + private static HttpServer createHttpServer(int port) throws IOException { + HttpServer httpServer = HttpServer.create(new InetSocketAddress(port), 0); + httpServer.createContext("/", new HttpHandler() { + @Override + public void handle(HttpExchange httpExchange) throws IOException { + byte[] content = ("Hello").getBytes("utf-8"); + System.out.println("server port:"+port+",handle request."+new Date()); + httpExchange.getResponseHeaders().add("Content-Type", "application/json; charset=UTF-8"); + httpExchange.sendResponseHeaders(200, content.length); + httpExchange.getResponseBody().write(content); + httpExchange.close(); + } + }); + return httpServer; + } + +} diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/NettyServerApplication.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/NettyServerApplication.java index e67b7961..06d83822 100644 --- a/02nio/nio02/src/main/java/io/github/kimmking/gateway/NettyServerApplication.java +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/NettyServerApplication.java @@ -1,18 +1,21 @@ package io.github.kimmking.gateway; +import com.jianjoy.http.SimpleHttpServer; import io.github.kimmking.gateway.inbound.HttpInboundServer; import java.util.Arrays; public class NettyServerApplication { - + public final static String GATEWAY_NAME = "NIOGateway"; public final static String GATEWAY_VERSION = "3.0.0"; - - public static void main(String[] args) { - String proxyPort = System.getProperty("proxyPort","8888"); + public static void main(String[] args) throws Exception { + //初始化后台服务 + SimpleHttpServer.main(args); + + String proxyPort = System.getProperty("proxyPort", "8888"); // 这是之前的单个后端url的例子 // String proxyServer = System.getProperty("proxyServer","http://localhost:8088"); @@ -22,14 +25,16 @@ public static void main(String[] args) { // 这是多个后端url走随机路由的例子 - String proxyServers = System.getProperty("proxyServers","http://localhost:8801,http://localhost:8802"); + String proxyServers = System.getProperty("proxyServers", "http://localhost:8801,http://localhost:8802"); int port = Integer.parseInt(proxyPort); - System.out.println(GATEWAY_NAME + " " + GATEWAY_VERSION +" starting..."); + System.out.println(GATEWAY_NAME + " " + GATEWAY_VERSION + " starting..."); HttpInboundServer server = new HttpInboundServer(port, Arrays.asList(proxyServers.split(","))); - System.out.println(GATEWAY_NAME + " " + GATEWAY_VERSION +" started at http://localhost:" + port + " for server:" + server.toString()); + System.out.println(GATEWAY_NAME + " " + GATEWAY_VERSION + " started at http://localhost:" + port + " for server:" + server.toString()); + + System.out.println("请访问接口地址:http://localhost:"+port+"/h1"); try { server.run(); - }catch (Exception ex){ + } catch (Exception ex) { ex.printStackTrace(); } } diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpRequestFilter.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpRequestFilter.java new file mode 100644 index 00000000..f5c88afb --- /dev/null +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpRequestFilter.java @@ -0,0 +1,16 @@ +package io.github.kimmking.gateway.filter; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.FullHttpRequest; + +/** + * Author: zhoujian + * Description: + * Date: 2021/5/23 22:59 + */ +public class MyHttpRequestFilter implements HttpRequestFilter { + @Override + public void filter(FullHttpRequest fullRequest, ChannelHandlerContext ctx) { + fullRequest.headers().set("x-start", System.currentTimeMillis()); + } +} \ No newline at end of file diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpResponseFilter.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpResponseFilter.java new file mode 100644 index 00000000..b99017d4 --- /dev/null +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/filter/MyHttpResponseFilter.java @@ -0,0 +1,20 @@ +package io.github.kimmking.gateway.filter; + +import io.netty.handler.codec.http.FullHttpResponse; + +import java.util.UUID; + +/** + * Author: zhoujian + * Description: + * Date: 2021/5/23 23:00 + */ +public class MyHttpResponseFilter implements HttpResponseFilter { + + + @Override + public void filter(FullHttpResponse response) { + response.headers().set("x-server-time", System.currentTimeMillis()); + response.headers().set("x-id", UUID.randomUUID().toString()); + } +} \ No newline at end of file diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/inbound/HttpInboundHandler.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/inbound/HttpInboundHandler.java index 69b40fde..bc946ad8 100644 --- a/02nio/nio02/src/main/java/io/github/kimmking/gateway/inbound/HttpInboundHandler.java +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/inbound/HttpInboundHandler.java @@ -1,8 +1,8 @@ package io.github.kimmking.gateway.inbound; -import io.github.kimmking.gateway.filter.HeaderHttpRequestFilter; import io.github.kimmking.gateway.filter.HttpRequestFilter; -import io.github.kimmking.gateway.outbound.httpclient4.HttpOutboundHandler; +import io.github.kimmking.gateway.filter.MyHttpRequestFilter; +import io.github.kimmking.gateway.outbound.okhttp.OkHttpOutboundHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.FullHttpRequest; @@ -16,14 +16,15 @@ public class HttpInboundHandler extends ChannelInboundHandlerAdapter { private static Logger logger = LoggerFactory.getLogger(HttpInboundHandler.class); private final List proxyServer; - private HttpOutboundHandler handler; - private HttpRequestFilter filter = new HeaderHttpRequestFilter(); - + private OkHttpOutboundHandler handler; + private HttpRequestFilter filter = new MyHttpRequestFilter(); + + public HttpInboundHandler(List proxyServer) { this.proxyServer = proxyServer; - this.handler = new HttpOutboundHandler(this.proxyServer); + this.handler = new OkHttpOutboundHandler(proxyServer); } - + @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); @@ -34,21 +35,33 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) { try { //logger.info("channelRead流量接口请求开始,时间为{}", startTime); FullHttpRequest fullRequest = (FullHttpRequest) msg; + String uri = fullRequest.uri(); + if (uri.contains("/h1")) { + handleRequest(fullRequest, ctx); + } + // String uri = fullRequest.uri(); // //logger.info("接收到的请求url为{}", uri); // if (uri.contains("/test")) { // handlerTest(fullRequest, ctx); // } - - handler.handle(fullRequest, ctx, filter); - - } catch(Exception e) { + +// handler.handle(fullRequest, ctx, filter); + + } catch (Exception e) { e.printStackTrace(); } finally { ReferenceCountUtil.release(msg); } } + private void handleRequest(FullHttpRequest fullRequest, ChannelHandlerContext ctx) { + filter.filter(fullRequest, ctx); + System.out.println("request header:"+fullRequest.headers()); + handler.handle(fullRequest, ctx); + } + + // private void handlerTest(FullHttpRequest fullRequest, ChannelHandlerContext ctx) { // FullHttpResponse response = null; // try { diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkHttpOutboundHandler.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkHttpOutboundHandler.java new file mode 100644 index 00000000..45181b91 --- /dev/null +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkHttpOutboundHandler.java @@ -0,0 +1,56 @@ +package io.github.kimmking.gateway.outbound.okhttp; + +import com.jianjoy.http.HttpUtil; +import io.github.kimmking.gateway.filter.MyHttpResponseFilter; +import io.github.kimmking.gateway.router.MyEndpointRouter; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; +import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; + +public class OkHttpOutboundHandler { + private static Logger logger = LoggerFactory.getLogger(OkHttpOutboundHandler.class); + private List endpoints; + + public OkHttpOutboundHandler(List servers) { + this.endpoints = servers; + } + + private MyEndpointRouter myEndpointRouter = new MyEndpointRouter(); + private MyHttpResponseFilter responseFilter = new MyHttpResponseFilter(); + + public void handle(FullHttpRequest fullRequest, ChannelHandlerContext ctx) { + String serverUrl = myEndpointRouter.route(endpoints); + System.out.println("random server url:" + serverUrl); + FullHttpResponse response = null; + try { + String htmlContent = HttpUtil.sendGet(serverUrl); + response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK + , Unpooled.wrappedBuffer(htmlContent.getBytes("UTF-8"))); + responseFilter.filter(response); + response.headers().set("Content-Type", "application/json"); + response.headers().setInt("Content-Length", response.content().readableBytes()); + System.out.println("response header:"+response.headers()); + } catch (Exception e) { + logger.error("调用后台接口出错", e); + response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT); + } finally { + if (fullRequest != null) { + if (!io.netty.handler.codec.http.HttpUtil.isKeepAlive(fullRequest)) { + ctx.write(response).addListener(ChannelFutureListener.CLOSE); + } else { + response.headers().set(CONNECTION, KEEP_ALIVE); + ctx.write(response); + } + } + } + + } +} diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkhttpOutboundHandler.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkhttpOutboundHandler.java deleted file mode 100644 index 5f194588..00000000 --- a/02nio/nio02/src/main/java/io/github/kimmking/gateway/outbound/okhttp/OkhttpOutboundHandler.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.github.kimmking.gateway.outbound.okhttp; - -public class OkhttpOutboundHandler { -} diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/MyEndpointRouter.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/MyEndpointRouter.java new file mode 100644 index 00000000..0501f742 --- /dev/null +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/MyEndpointRouter.java @@ -0,0 +1,21 @@ +package io.github.kimmking.gateway.router; + +import java.security.SecureRandom; +import java.util.List; + +/** + * Author: zhoujian + * Description: 随机路由 + * Date: 2021/5/23 23:03 + */ +public class MyEndpointRouter implements HttpEndpointRouter { + private static final SecureRandom RANDOM = new SecureRandom(); + + @Override + public String route(List endpoints) { + int randomIndex = RANDOM.nextInt(endpoints.size()); + return endpoints.get(randomIndex); + } + + +} \ No newline at end of file