jetty 透明代理的实现
来源:互联网 发布:数据库课程设计实验 编辑:程序博客网 时间:2024/03/29 04:13
背景
一提到proxy,大家首先想到就是squid、varnish、apache、lighttpd之类,接下来我们看看jetty8中的ProxyServlet是如何实现这个功能的
ProxyServlet主要用到了continuation和http client两个技术点,如果了解了我的前几篇博文
- jetty io:http://blog.csdn.net/pwlazy/article/details/7162992
- jetty continuation:http://blog.csdn.net/pwlazy/article/details/7299719
- jetty http client:http://blog.csdn.net/pwlazy/article/details/7389204
理解ProxyServlet就很容易了
配置
ProxyServlet官方配置如下:
<servlet> <servlet-name>TransparentProxy</servlet-name> <servlet-class>org.eclipse.jetty.servlets.ProxyServlet$Transparent</servlet-class> <async-support>true</async-support> <init-param> <param-name>Prefix</param-name><param-value>/javadoc-proxy</param-value> </init-param> <init-param> <param-name>ProxyTo</param-name><param-value>http://download.eclipse.org/jetty/stable-8/apidocs</param-value> </init-param> <init-param> <param-name>HostHeader</param-name><param-value>download.eclipse.org</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>TransparentProxy</servlet-name> <url-pattern>/javadoc-proxy/*</url-pattern> </servlet-mapping>
servlet的初始化
- host的黑名单/白名单
- httpclient,比如最大线程、某个服务的最大连接数、请求超时时间、连接空闲时间等等
servlet的运行
- 根据请求和配置确定目标url
- 定义httpexchange,包括各种callback
- 拷贝原始请求中的header到httpexchange,需要排除一些不需要的header比如connection、keep-alive(详见ProxyServlet中定义的_DontProxyHeaders)
- 设置proxy的专有头部,比如X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Server
- 注册continuation
- 调用httpclient发送httpexchange
内部运行原理
- ProxyServlet使用了两个线程池来完成工作,一个jetty server使用,一个jetty http client使用
- server中的work线程将请求任务扔给http clientt中的worker线程,就会回收到server线程池中(这是第一次异步)
- http client中的worker线程请求后台server的内容(这是第二次异步,因为请求过程一旦不能立即返回,worker线程就会把请求注册到select线程然后返回,这个我在博文http://blog.csdn.net/pwlazy/article/details/7389204详细描述了)
- 一旦backend后端返回,就会调用exchange中定义的callback(这是第一次callback【时髦的说法应该是事件驱动】,也是http client级别的callback)
- callback接下来也会调用continuation的complete方法通知jetty server,后台操作完成(这是第二次callback,是server级别的callback,通过continuation完成,这个过程我在博文http://blog.csdn.net/pwlazy/article/details/7299719也详述了)
- 此时jetty server又会使用一个worker线程完成最后的输出到浏览器
小结
- ProxyServlet综合使用了continuation和httpclient
- ProxyServlet类似场景还是大量存在的,比如我们的web应用经常会调用后端的服务,比如cache、db、其他服务等
- 如果调用后端的服务能够做到象http client这样事件驱动,那么就可以很完美的实现整个web 应用完全无阻塞
- 否则想仅仅使用一个应用级别线程池+continuation实现完全无阻塞简直就是白搭,因为那个压力完全会在应用线程池这边
- 可见web 应用完全无阻塞是前提条件是所有的io点都必须无阻塞,这个条件看起来是有些高了,恐怕很多服务驱动程序都需要重写,鸭梨山大
- jetty 透明代理的实现
- 本地透明代理的实现
- HTTP透明代理的java实现
- [ZT]squid中实现https的透明代理
- 透明代理和真实代理的区别
- 透明代理发送的IP
- 实现TCP透明代理(附下载)
- Python入门:python实现http透明代理
- iptables NAT+squid实现透明代理
- Ubuntu编译运行Redsocks2实现透明代理
- 标准代理,透明代理,反响代理的区别
- 正向代理,反向代理和透明代理的区别
- 正向代理、反向代理和透明代理的讲解
- 透明代理
- jetty线程池的实现
- Linux下透明代理+Privoxy实现页面相关的广告植入
- Linux下的透明代理技术
- Linux下的透明代理技术
- 再说C++模板类的一些使用技巧
- oracle的闪回
- 黑马程序员-线程和socket
- fput(); fgetc();
- <<Windows CE 系统进程外组件应用开发 >> 文章的解读
- jetty 透明代理的实现
- linux 动态链接库的创建和使用--静态连接
- Sqlserver 数据库计算时间差
- Rails 笔记(一)
- waitpid
- 开弓没有回头箭——我的程序员之路
- CODE::BLOCKS 使用手册 及 WIKI
- 一步步 学数据结构 之 三
- 关于Ogre自带输入系统OIS(Object-Oriented Input System)的源码分析