如何设计一个web容器
开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探讨实现的思路,并不涉及过多的具体实现。把它分解划分成若干模块和组件,每个组件模块负责不同的功能,下图列出一些基本的组件,并将对每个组件进行介绍。

连接接收器
主要的职责就是监听是否有客户端套接字连接并接收socket,再将socket交由任务执行器(线程池)执行。不断从系统底层读取socket,做尽可能少的处理,再扔进线程池。为什么强调要做尽可能少的处理?这里关系到系统性能问题,过多的处理会严重影响吞吐量。因为一般只有一个接收器(一条线程负责套接字接收工作),所以它对每次接收处理的时间长短将很可能对整体性能产生影响。于是接收器所干的活都是非常少且简单的,仅仅维护了几个状态变量、流量控制闸门的累加操作、serverSocket的接收操作、设置接收到的socket的一些属性、将接收到的socket放入线程池以及一些异常处理。其他需要较长时间处理的逻辑就交给了线程池,例如对socket底层数据的读取,对http协议报文的解析及响应客户端的一些操作等等。

连接数控制器
对于一台机器而言,访问请求的总流量有高峰期且服务器有物理极限,为了保证web服务器不被冲垮我们需要采取一些措施进行保护预防,需要稍微说明的此处的流量更多的是指套接字的连接数,通过控制套接字连接个数来控制流量。其中一种有效的方法就是采取流量控制,它就像在流量的入口增加了一道闸门,闸门的大小决定了流量的大小,一旦达到最大流量将关闭闸门停止接收直到有空闲通道。计数器可用JDK的AQS框架实现。

套接字工厂
不同的使用场合可能需要不同的安全级别,例如在支付相关的交易就必须对信息加密后再发送,这其中还涉及到密钥协商的过程,而在另外一些普通场合则无需对报文加密。反应到应用层则是使用http与https的问题。
简单讲TLS\SSL协议给每次通信①提供认证服务,认证本次会话实体身份的合法性。②提供加密服务,强加密机制能保证通信过程中的消息不会被破译。③提供防篡改服务,利用Hash算法对消息进行签名,通过验证签名保证通信内容不被篡改。
http协议对应Socket,而https则对应SSLSocket。如何生成Socket及SSLSocket则交由套接字工厂。

任务定义器——Task
定义需要执行的任务,告诉线程池要执行什么样的任务。任务主要分为三点:处理socket并响应客户端、连接数计数器减一、关闭socket。其中对socket的处理是最重要也是最复杂的,它包括对底层socket字节流的读取、http协议请求报文的解析(请求行、请求头、请求体等信息的解析)、根据请求行解析得到路径去寻找相应主机上web项目的资源、根据处理的结果组装好http协议响应报文输出到客户端。

任务执行器
一个拥有最大最小线程数限制的线程池,之所以称之为“任务执行器”是因为线程池可以看做是启动了若干线程不断检测某个任务队列,一旦发现有需要执行的任务则执行。最大最小线程数限制、多余线程回收时间限制、超出最大线程数时线程池做出的拒绝动作等等。

报文读取
用于向操作系统底层读取来自客户端的报文并提供缓冲机制。报文复制到desBuf。

报文输出
用于向操作系统底层写入由web容器处理后的报文并提供缓冲机制。将报文outputBuf通过缓冲区写入到操作系统。

输入过滤器
在这个读取的过程中希望做一些额外的处理,并且这些额外处理可能是根据不同条件做不同的处理,考虑到程序解耦与扩展,于是引入过滤器。通过一层层的过滤器完成过滤操作后才能到desBuf,这个过程就像被加入了一道道处理关卡,经过关卡都会被执行相应操作,最终完成源数据到目的数据的操作。

输出过滤器
与输入过滤器功能类似,用于在报文输出的时候。

报文解析器
提供解析http协议各个部分的能力。

请求生成器
按照面向对象的思想,把每个请求过程中与请求相关的属性及协议字段等抽象成一个Request对象。包括请求行、请求头、请求体三部分信息,在处理过程中需要什么值可直接从request对象中获取。为实现servlet标准提供方便。

响应生成器
与请求相对应,需要一个响应对象生成器。包括响应行、响应头、响应体三部分信息,在处理结果相关值可直接设置到response对象中。为实现servlet标准提供方便。

地址映射器
地址映射器是请求与各个web项目、各个资源的路由器。一个请求的访问根据路径被映射找到响应的资源输出给请求客户端。

生命周期
为了进一步模块化,整个容器拥有很多组件,这些组件可能在不同的时刻需要做不同的事件,需要一个生命周期统一把所有组件管理起来。例如所有组件的启动、停止、关闭等操作都抽离由生命周期统一管理,就可以方便管理这些组件的生命周期。希望在某某状态事情发生之前之后做点什么?添加一个生命周期监听器即可优雅实现。

JMX管理器
系统运行状态的监控及管理,服务器性能、服务器相关参数的收集、JVM负载、web连接数、线程池、数据库连接池、缓存管理、配置文件重新加载等方面。可提供一些远程可视化管理,实时性高。同时也为分布式系统的管理提供了一个解决方案。

Web载入器
WebLoader用于加载web应用项目,一个web容器可能包含了若干个web应用。为了达到lib及servlet的隔离,对于每个web应用要使用不同的类加载器ClassLoader,且这些类加载器不是父子关系,以此达到class隔离效果,即一个web应用的lib不会被其他web应用使用。

会话管理器
会话管理器主要对session进行管理,包括:①生成sessionid,一般cookies或url未带jsessionid值则认为不存在会话,需要重新生成sessionid用作会话id。②很多客户端的会话都保存在服务器中,对于超时的会话要定期清理以确保服务器内存不会浪费。③对于一些重要的会话可以持久化到磁盘,需要时可重新加载到内存中使用。

运行日志
对运行时一些警告、异常、错误进行记录。

访问日志
访问日志一般会记录客户端的访问相关信息,包括客户端ip、请求时间、请求协议、请求方法、请求字节数、响应码、会话id、处理时间等等。访问日志可以统计访问用户的数量、访问时间分布等规律及个人爱好等等,这些数据可以帮助公司在运营策略上做出抉择。

安全管理器
Web项目运行在web容器平台上,这就好比将一个应用嵌入到一个平台上面运行,要使嵌入的程序能正常运行,首先平台要能安全正常运行。并且要最大程度做到平台不受嵌入的应用程序影响,两者在一定程度上达到隔离的效果。启动时通过-Djava.security.manager -Djava.security.policy==web.policy指定policy文件,此文件定义了各种权限。

运行监控&远程管理
提供一个可以实时监控web容器运行状态的平台,并且能进行远程管理。

集群
集群一般有两种:①负载均衡集群,一般是通过一定的分发算法把访问流量均匀分布到集群里面的各个机器上进行处理。②高可用集群,集群通信把若干机器连接起来,这种集群更偏重的是当集群中某个机器发生故障后能通过自动切换或流量转移等措施来保证整个集群对外的可用性。
web一般请求都是无状态,可以直接做集群,但涉及session则属于有状态,需要使用集群通信技术进行session拷贝。相关技术包括组播、单播。

Servlet引擎
servlet引擎利用反射把web应用中的servlet及jsp生成对象并放入servlet对象池中,并根据实际调用相应的方法。web应用将业务逻辑处理都放在dopost或doget方法中,web容器处理请求时就会按照这里定义好的处理逻辑进行处理,处理完响应客户端。

JSP编译器
按照规范JSP最终都是被编译成servlet执行,所以要按照规范对jsp文件进行编译。JSP编译器其实就是对jsp语法进行翻译,根据jsp语法处理。

一个web容器基本包含以上介绍的组件的功能,根据各个组件模块进行实现即可搭建起一个可以让你的web运行起来的web容器。
喜欢java的同学可以交个朋友
如何设计一个web容器的更多相关文章
- 集群: 如何在spring 任务中 获得集群中的一个web 容器的端口号?
系统是两台机器, 跑四个 web 容器, 每台机器两个容器 . nginx+memcached+quartz集群,web容器为 tomcat . web 应用中 用到spring 跑多个任务,任务只能 ...
- servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解1
servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解 (2013-06-19 19:30:40) 转载▼ servlet的非线程安全,action的线程安全 对提交 ...
- Nginx可以说是标配组件,但是主要场景还是负载均衡、反向代理、代理缓存、限流等场景;而把Nginx作为一个Web容器使用的还不是那么广泛。
Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛. 用Nginx+Lua(OpenResty)开发高性能Web ...
- 如何设计一个可用的web容器
之前在另外一个平台(http://www.jointforce.com/jfperiodical/article/1035)发表的一篇文章,现在发布到自己的博客上. 开发一个web容器涉及很多不同方面 ...
- 一文读懂tomcat组件--一个web服务器的架构演化史
1. tomcat是谁? 2. tomcat可以做什么? tomcat是一个web容器,可以将web应用部署到tomcat,由它提供web服务,一个web容器中可以部署多个web应用,这些we ...
- 如何设计和实现一个web app
web app简介 web app其实不算是什么新鲜的东西,相比于传统的web和传统的app,web app这种web和app相结合的产物有的优点如下: 1. 开发上web app更有便捷性,ios开 ...
- JAX-WS 学习二:基于WEB容器,发布WebService
WebService 的发布通过调用 Endpoint.publish() 方法来启动一个java内嵌的WEB容器来实现的,如果要将WebService部署到一个WEB容器中去,需要使用jax-ws提 ...
- web容器 web服务器 servlet/jsp容器 之间的区别和关系
今天学习tomcat时发现一篇写的比较好的文章,故分享给大家 Web服务器(软件): Apache http server, 这个它的网址,http://httpd.apache.org/downlo ...
- 如何在集群中获得处理本次请求的web容器的端口号?
系统四台机器,每台机器部署四个Tomcat Web容器.现需要根据端口号随机切换到映射的数据源,若一台机器一个Tomcat则用IP识别,可现在一台机器四个Tomcat,因此还需要获得Web容器的端口号 ...
随机推荐
- zabbix API基本使用方法介绍
前言: 以下内容根据zabbix 3.2官方文档总结:https://www.zabbix.com/documentation/3.2/manual/api 此文档只是简单的介绍API的基本使用,关于 ...
- Bootstrap3 表单-被支持的控件:文本域
支持多行文本的表单控件.可根据需要改变 rows 属性. <textarea class="form-control" rows="3"></ ...
- Rails报找不到sanitize和raw方法的解决
以下一段代码作用是对html字符串做过滤作用: sanitize(raw(content.split.map{ |s| wrap_long_string(s) }.join(' '))) 不过实际会报 ...
- C语言完美体系
**第 1 篇 C 语言第一阶段 13 1.1C 语言第一阶段--语言课程概述 13 1.1.1 什么是语言,什么是 C 语言 13 1.1.2 基本常识 14 1.1.3 人与计算机之间的更好的交互 ...
- Linux 性能监测:Memory
这里的讲到的 "内存" 包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为 ...
- Android app内存管理的16点建议
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiopshared memory(共享内存) Android通过下面几个方式在不同的Process中来共享RAM: 每一个app的proc ...
- EJB通过ANT提高EJB应用的开发效率、开发具有本地接口的无状态bean、开发有状态bean
把jboss集成进eclipse 关闭Jboss控制台按Ctrl+c,在MyEclipse→Servers→Jboss里面可以配置JBoss. 通过ANT提高EJB应用的开发效率 在HelloWorl ...
- 一个 Linux 上分析死锁的简单方法
简介 死锁 (deallocks): 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这 ...
- win8如何共享文件夹
最近小编接手了市委组织部考核项目,各种文档.ER图.原型图,组员之间需要拷来拷去,很不方便,通过飞信,QQ传输吧,文件太大,网络太慢,所以还是不行,于是小编就想起来要共享,以前也映射过别人的共享,觉得 ...
- 【java虚拟机系列】JVM类加载器与ClassNotFoundException和NoClassDefFoundError
在我们日常的项目开发中,会经常碰到ClassNotFoundException和NoClassDefFoundError这两种异常,对于经验足够的工程师而言,可能很轻松的就可以解决,但是却不一定明白为 ...