前束
本篇博客没有给出一个完善的技术解决方案,使用java搭建代理服务器是处理本人想要实现主备切换的broker而产生的想法,由于能力,时间和精力的限制,目前只能将想法的大致内容实践一下,这里只是分享一些这两天在这上面做出的一些探索,以免其他人重蹈覆辙。
简述
需求简述为通过JAVA实现一个代理服务器,客户端的Http请求全部指向代理服务器,代理服务器基于一定的策略将请求转发给后台服务器,(这里的策略就比较核心,能够实现很多特殊的需求,比如我想实现的主备切换的功能,通过添加主机检测模块,如果主机检测模块检测到主服务器down了,那么程序能够顺利的迁移到备用服务器上)。
技术准备
Http Request和Response的基础知识
java socket/Serversocket 类的使用技巧
问题分析
问题可以简化为
1代理服务主机将客户机与代理服务主机之间的请求截获,然后直接将信息转发给目标主机
2代理服务主机将目标主机的回应直接转发给客户机。
那么
代理服务主机可以通过socket直接获取客户机发送到本机指定端口的数据报文,那么通过分析内容可以得到客户机想要发送给目标主机的信息
代理服务主机可以通过httpRequest的方式再次重新请求,将原来请求中的内容转发给目标主机,之后将目标主机的回应组织成Http Response的形式转发给客户机。
Demo
代码中只演示的代理服务器中的通信过程,中间的源信息的分析 以及返回值得构造还没有做,另外还存在多线程控制等问题,建议参考者将精力花在解决以上问题上面。
import java.net.* ; import java.io.* ; class ActionSocket extends Thread{ private Socket socket = null ; public ActionSocket(Socket s){ this.socket = s ; } public void run(){ try{ this.action() ; }catch(Exception e){ e.printStackTrace(); } } public void action() throws Exception { if (this.socket == null){ return ; } InputStream cis = this.socket.getInputStream(); URL url = new URL("http://www.baidu.com"); HttpURLConnection action = (HttpURLConnection) url.openConnection(); InputStream sis =action.getInputStream(); OutputStream cos = socket.getOutputStream(); int length; byte bytes[] = new byte[1024]; while(true){ try { if ((length = sis.read(bytes)) > 0) { cos.write(bytes, 0, length);//将http请求头写到目标主机 System.out.println(new String(bytes)); cos.flush(); } else if (length < 0) break; } catch (Exception e) { } } socket.close(); cis.close(); } } public class SocketServer{ public static void main(String args[])throws Exception{ ServerSocket server = new ServerSocket(8888); while(true){ Socket socket = server.accept(); ActionSocket ap = new ActionSocket(socket); ap.start(); } } }
参考
http://www.fullstackdevel.com/computer-tec/network/731.html
http://stackoverflow.com/questions/6876266/java-net-connectexception-connection-refused
http://www.freebuf.com/articles/web/21832.html