舉個例子,比如我訪問百度(www.baidu.com),但是我們其實並不知道百度內部到底有多少臺伺服器、百度是怎麼處理這次請求的以及我們應該訪問那臺伺服器。我們只是知道我訪問了百度(www.baidu.com)的域名或者公網IP,然後就返回了結果。至於百度前置閘道器服務根據規則進行轉發(至於轉發到那臺伺服器,由負載均衡處理)以及後端伺服器處理對外面的使用者來說是隱藏的。
注意⚠️反向代理和正向代理的區別。
JAVA如何實現反向代理Java實現反向代理功能其實非常的簡單,因為在Github中有一個開源專案(https://github.com/mitre/HTTP-Proxy-Servlet)HTTP-Proxy-Servlet基於Servlet實現了請求代理。同時這個專案Http請求是依賴於Apache HttpClient專案。
HTTP-Proxy-Servlet如何使用實現反向代理首先:引入HTTP-Proxy-Servlet專案依賴
<dependency> <groupId>org.mitre.dsmiley.httpproxy</groupId> <artifactId>smiley-http-proxy-servlet</artifactId> <version>1.11</version></dependency>
第二步:配置路由策略,註冊Servlet
@Configurationpublic class ProxyServletConfig { @Bean public Servlet getProxyServlet() { return new ProxyServlet(); } /** * 這裡可以多加幾個,但是servlet名字需要不一樣 */ @Bean public ServletRegistrationBean proxyServletRegistrationBean() { // 配置路由策略 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(getProxyServlet(), ContextConstants.PROXY_URL_PATTERN); Map<String, String> params = new HashMap<>(); // 路由策略 params.put("targetUri", "http://localhost:8080/proxy/error"); params.put(ProxyServlet.P_LOG, "true"); servletRegistrationBean.setInitParameters(params); return servletRegistrationBean; }}
其實這樣,啟動專案就可以實現反向代理的功能了。但是這種是靜態的配置,如果我要基於資料庫實現動態的方向代理服務應該怎麼做呢?
實現基於資料庫動態方向代理還記得在第二步中有一個ProxyServlet嗎?其實我們可以繼承這個類實現裡面的service(HttpServletRequest request, HttpServletResponse response)方法即可。這裡注意這兩行程式碼是反向代理的關鍵,因為是透過attribute中這兩個屬性進行判斷的。
protected static final String ATTR_TARGET_URI = ProxyServlet.class.getSimpleName() + ".targetUri";protected static final String ATTR_TARGET_HOST = ProxyServlet.class.getSimpleName() + ".targetHost";@Overrideprotected void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException { // ...(忽略)... servletRequest.setAttribute(ATTR_TARGET_URI, proxyTarget.getTargetUri()); servletRequest.setAttribute(ATTR_TARGET_HOST, gson.fromJson(gson.toJson(proxyTarget.getHttpHost()), HttpHost.class)); // ...(忽略)...}
看到這裡聰明的同學們肯定知道應該怎麼做了吧,只要在這裡讀取資料庫中的路由規則,然後將剛剛ProxyServletConfig配置類中的路由規則寫成(攔截(/*)所有路徑並targetUri寫成固定即可,反正targetUri已經失效),還要把註冊的Servlet改成自己實現的Servlet即可。
怎麼樣,是不是非常簡單實用~