设为首页 收藏本站
查看: 897|回复: 0

[经验分享] 使用apache alias/sendfile功能实现高性能的图片服务

[复制链接]

尚未签到

发表于 2017-1-13 09:26:54 | 显示全部楼层 |阅读模式
  


问题的提出

在java webapp开发过程中有很多需要下载图片的需求,一般情况下我们都是用tomcat/jetty等类似的java web 容器提供java web程序运行服务,由于web容器可以直接提供http服务,所以架构师往往就直接使用java容器来直接提供图片的下载服务,这种做法往往带来的大量用户下载是web容器运行效率不佳,有时会影响servlet页面的处理效率。尽管现代的web容器做了深度优化,处理效率比之以前大大提高,但是一旦用户数量上去后,依然存在进程假死,不提供服务的问题。


深入分析


为什么使用java容器提供图片下载会出现这样的情况呢?我们首先需要看一下磁盘io的过程或者说步骤:


  • 应用程序通过io api发出数据读取请求
  • 如果是java程序,java进程通过jvm对操作系统发出请求
  • 操作提供接收到指令从磁盘读取数据,现代操作系统都具备缓存功能,如果缓存中存在符合要求的数据块,则直接返回
  • 操作系统对磁盘发出去读取数据请求,现代的磁盘一般也有缓存功能,如果缓存中存在符合要求的数据块,则直接返回
  • 操作系统监控磁盘的数据读取操作,如果读取完成,此时数据被放在称作内核态的内存区域,此时操作系统需要把数据复制到用户态的内存中

这样数据有一个复制的过程,会消耗更多的资源和时间,如果使用java.io话,jvm会把复制到用户态内存的数据切成小块在返回个java app,这样java处理文件的效率会更加低效。现在的操作系统提供了一种称之为“mmap”的技术,可以直接把内核态的内存地址映射成用户态的地址,这样减少了用户态和内核态内存拷贝的消耗,提高了性能。自从jdk1.4,java也引入了使用mmap的技术,提高了效率。一般情况下,web容器提供文件服务时首先需要读取文件数据到内存然后通过tcp发送个客户端浏览器,这个是通过jvm来处理的,一般情况下多了jvm这一层,效率并不会产生太大影响,但一旦用户数上来这看似很小的性能消耗会被无限放大,直接现象就是web容器不能提供服务。另一方面io本身就是一个相对慢的操作,即使是使用c开发,当用户量急剧上升时也可能会出现问题。所以现代操作系统提供了一个叫sendfile的技术,这是在操作系统级别做了优化的技术,可以提供高效的文件读取和传输,很多web服务器比如apache/nginx/lighthttpd都基于这个技术提供了组件,但遗憾的是无论是tomcat还是jetty都还不能提供这个支持。还有一个问题是java的tcp通讯模型问题,虽然java底层已经支持epoll模式,但jdk层的封装上还是selector模式,这与操作系统原生的epoll模式在网络接入和处理上存在差距。基于这3个方面的原因造成了java web容器的问题。


解决方案



通用的技术解决方案


一般的解决方案的核心就是:让专业的人做专业的事。java web容器的作用是运行java web程序,运行动态页面,读取数据库,处理业务逻辑,对于一下静态的页面、图片、文件等直接让apache、nginx或者lighthttpd来提供服务。同时apache层还可以作为负载均衡,动态转发http请求到多个web 容器。


apache提供的图片服务方案



alias方案


apache支持别名技术,所谓的别名就是当用户请求一个资源时,apache根据配置规则自动把请求的资源转换到一个看似毫不相关的本地文件系统资源,比如:
Alias /foo/bar /baz
Alias /foo /gaq
当用户请求/foo/bar时,apache会自动从/baz获取资源,结合url rewrite可以提供更为强大的功能。这种方案在处理不需要权限判断的资源时非常有效,但需要权限判断的资源则不适合。

sendfiles方案


apache提供sendfiles技术的支持,需要安装一个特定的组件。其核心原理是:web程序通过response写入一个特定的header:X-Sendfile,当apache收到该response时会自动识别,然后自动读取需要下载的文件路径,并且读取文件发送至客户端浏览器。这样就可以进行权限判断了,文件下载的步骤是:


  • 客户端请求一个文件
  • apache转发原始请求至web容器
  • web app进行权限判断
  • web app根据请求参数查询出文件路径,并且写header
  • apache截获response,根据header信息判断是否使用sendfiles技术,发送数据

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-327780-1-1.html 上篇帖子: 对apache中并发控制参数prefork理解和调优 下篇帖子: apache与多个tomcat集成 单台主机多站点场景
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表