1.美团动态线程池思路框架(DynamicTp)之动态调整Tomcat、码下Jetty、码下Undertow线程池参数篇
2.Java学习资源
3.dubbo十层架构?
4.docker jetty10 å¯å¨ war
5.四种方法实现http服务
6.ç®è¿°ä¸ä¸Javaä¸çweb容å¨ï¼ä¸¾å 个ä¾åä¹è¡
美团动态线程池思路框架(DynamicTp)之动态调整Tomcat、码下Jetty、码下Undertow线程池参数篇
动态线程池框架(DynamicTp)的码下adapter模块,作为第三方组件线程池管理的码下客户裂变系统源码适配器,旨在使如Tomcat、码下Jetty和Undertow等Web服务器内置的码下线程池具备动态参数调整、监控告警等增强功能。码下通过该模块,码下用户可利用Spring的码下事件机制监听并管理这些第三方组件的线程池,实现与核心模块的码下解耦。
adapter模块已成功接入SpringBoot内置的码下三大WebServer,包括Tomcat、码下Jetty和Undertow的码下线程池管理。通过监听机制,动态Tp框架能够及时响应这些组件的线程池变化,提供实时监控和灵活调整策略。
具体实现上,针对Tomcat、Jetty和Undertow的线程池管理,需要深入理解其内部处理流程。这些组件并未直接使用Java Util Concurrency(JUC)提供的线程池实现,而是自定义了线程池或扩展了JUC的实现,如Tomcat就采用了自定义的ThreadPoolExecutor类,通过继承或扩展JUC的抽象类来定制线程池行为。
以Tomcat为例,其内部线程池的实现中,继承自JUC原生ThreadPoolExecutor或其抽象类AbstractExecutorService。在执行任务时,Tomcat首先调用父类方法处理,然后根据任务队列类型(如TaskQueue)和线程池当前状态(如线程数、提交任务数、队列状态)进行一系列复杂判断,以决定是否创建新线程、添加任务至队列或执行拒绝策略。这种设计使得Tomcat能够高效管理请求,同时优化资源利用,避免过度创建线程导致的性能下降。
Jetty和Undertow的内部线程池实现原理与Tomcat类似,均基于JUC框架进行定制,以满足其特定的性能优化和扩展需求。通过分析这些组件的预售源码源码,可以深入了解其线程池管理策略,为后续性能调优提供宝贵信息。
动态线程池框架(DynamicTp)的引入,为Web服务器性能调优提供了强大的工具,允许用户动态调整线程池参数,提升系统响应速度和资源利用率。使用DynamicTp框架,用户可以更灵活地管理第三方组件的线程池,实现业务与开源贡献的双赢。
欢迎使用DynamicTp框架,探索更多性能优化的可能性。下期将分享在使用过程中遇到的Tomcat版本不一致导致的监控线程停滞问题,通过这一案例深入理解ScheduledExecutorService的运行机制。敬请期待。
如需交流或合作,请联系我,期待与您一起成长:
微信:yanhom
公众号:CodeFox
Java学习资源
Java Commons Java tutorial WebService常用第三方webservice IDEEclipse Eclipse GUI Plugin Eclipse根据java代码生成UML图 Tomcat Hudson Jenkins Atlassian Bamboo TeamCity JUnit DbUnit JMockit TestNG ReportNG SLF4J Log4j Logback Log4E代码评审 guava jga Java Class Dependency Analyzer OW2Forge Rock apache Apache Commons sandbox中的项目无法直接通过maven进行依赖,必须通过svn下载源码,部署到本地maven仓库中。例如对于sandbox中的classscan项目: # 项目地址:commons.apache.org/sand... svn checkout mons/sandbox/classscan classscan cd classscan 当install带有parent的maven项目时,如果没有把parent一并install,其它项目引用时会出现 mvn install--Failed to read artifact descriptor for org.apache.maven.plugins:maven-source-plugin:jar:2.1.2 cd parent (classscan/parent) mvn clean package install -DskipTests cd ../api (classscan/api) mvn clean package install -DskipTests cd ../bcel (classscan/bcel) mvn clean package install -DskipTests 在pom.xml中添加依赖 org.apache.commons.classscan bcel 0.2-SNAPSHOT org.apache.commons.classscan api 0.2-SNAPSHOT Eclipse中Update Project,选择Force Update of Snapshots/Releases Apache HttpComponents Maven and M2Eclipse maven快速下载某个jar包依赖的所有jar 经常碰到这种事情:在一些非maven工程中(由于某种原因这种工程还是手工添加依赖的),需要用到某个新的类库(假设这个类库发布在maven库中),而这个类库又间接依赖很多其他类库,如果依赖路径非常复杂的话,一个个检查手动下载是很麻烦的事。下面给出一个便捷的办法,创建一个新目录里面建一个maven pom文件, 添加需要依赖的类库: 4.0.0 com.dep.download dep-download 1.0-SNAPSHOT com.xx.xxx yy-yyy x.y.z 在这个目录下运行命令,所有跟这个类库相关的直接和间接依赖的jar包都会下载到 ./target/dependency/下 杂项 间接依赖的jar包能否直接使用 如果工程依赖A.jar,并用maven设置好依赖,同时A.jar会依赖B.jar,所以maven在下载A.jar的同时会下载B.jar,这时如果项目发现需要使用B.jar中的一些内容,在maven中不必从新设置依赖,可以在工程中直接使用。 把某个本地jar包安装到本地仓库中 mvn install:install-file -DgroupId=“edu.jiangxin” -DartifactId=”gcu” -Dversion=“1.0.0” -Dpackaging=”jar” -Dfile=“D:\CS\J2EE\lib\edu.jiangxin.gcu-1.0.0.jar” 把某个本地jar包部署到某个远程仓库中 mvn deploy:deploy-file -DgroupId=“edu.jiangxin” -DartifactId=”gcu” -Dversion=“1.0.0” -Dpackaging=”jar” -Dfile=“D:\CS\J2EE\lib\edu.jiangxin.gcu-1.0.0.jar” -Durl= yourlocalrepository:... -DrepositoryId=internal bintray bintray.com/ Ant Eclipse Color Themes MyEclipse EclEmma eCobertura JavaNCSS Clover(收费) CAP (code analysis plugin) Visual Performance Analyzer VisualVM JD(Java Decompiler) 注:不支持命令行使用,因而很难批量编译。 jad 注:jad支持命令行方式使用,最新版本为1.5.8g,支持的class版本过低。经常出现问题:The class file version is .0 (only .3, .0 and .0 are supported)。还有一个工具uuDeJava,也是基于jad,所以估计也难以避免这个问题。 jdec JODED J Java Decompiler 注:收费软件,没有试用过 ProGuard FindBugs PMD Metric Jdepend SourceHelper Structure inFusion SourceMonitor Simian CheckStyle CCTE J-Technologies一家(收费) FORTIFY SCA(收费) coverity(收费) klocwork(收费) GProf Dot and Graphviz sikuli exe4j JBoss GlassFish Virgo Jetty cpDetector EZMorph Apache Shiro Struts Spring Hibernate iBATIS/MyBatis appfuse TopLink json neethi XML SAXON jsoup HTML Parser Java port of Mozilla charset detector(jchardet) JMX jsch * yFiles Themodbustcp 源码 yFiles diagramming software components are extensive class libraries that enable you to add high-quality diagramming functionality to your own software applications OpenLDAP Protobuf zip4j JFlex JavaCC sablecc Xtext antlr cglib javassist jclasslib ical4j 分词规则引擎 Drools jBPM OpenAS2 Java Native Access (JNA) mpi Java eBus JACOBA Apache POI - the Java API for Microsoft Documents iText(AGPL) aspose MVEL(Drools) OGNL(Struts) SPEL(Spring) JSP EL freemarker Velocity Auroradubbo十层架构?
Dubbo简介
Dubbo是Alibaba开源的分布式服务框架,它按照分层的方式来架构,使用这种方式可以使各层解耦。
Dubbo在调用远程的服务的时候再本地有一个接口,就想调用本地方法一样去调用,底层实现好参数传输和远程服务运行结果传回之后的返回。
Dubbo的特点:
(1)它主要使用高效的网络框架和序列化框架,让分布式服务之间调用效率更高。
(2)采用注册中心管理众多的服务接口地址,当你想调用服务的时候只需要跟注册中心询问谈歼瞎即可,不像使用WebService一样每个服务都得记录好接口调用方式。
(3)监控中心时实现服务方和调用方之间运行状态的监控,还能控制服务的优先级、权限、权重、上下线等,让整个庞大的分布式服务系统的维护和治理比较方便。
(4)高可用,如果有服务挂了,注册中心就会从服务列表去掉该节点,客户端会像注册中心请求另一台可用的服务节点重新调用。同时注册中心也能实现高可用(ZooKeeper)。
(5)负载均衡,采用软负载均衡算法实现对多个相同服务的节点的请求负载均衡。
Dubbo需要四大基本组件:Rigistry,Monitor,Provider,Consumer。
1、含空监控中心的配置文件-dubbo.properties文件
(1)容器改改,监控中心是在jetty和spring环境下运行,依赖于注册中心,日志系统是log4j
dubbo.container=log4j,spring,registry,jetty(2)监控服务的名称,监控系统对整个Dubbo服务系统来说也是一个服务
dubbo.application.name=simple-monitor(3)服务的所有者,这是Dubbbo的服务的功能,可以指定服务的负责人
dubbo.application.owner=coselding(4)注册中心的地址,配置后监控中心就能通过注册中心获取当前可用的服务列表及其状态,在页面向你汇报Dubbo中的服务运行情况。
dubbo.registr.address=multicast://{ ip}:{ port}//广播dubbo.registr.address=zookeeper://{ ip}:{ port}//zookeper
dubbo.registr.address=redis://{ ip}:{ port}//redis
dubbo.registr.address=dubbo://{ ip}:{ port}//dubbo
(5)dubbo协议端口号
dubbo.protocol.port=(6)jetty工作端口号
dubbo.jetty.port=(7)工作目录,用于存放监控中心的数据
dubbo.jetty.directory=${ user.home}/monitor(8)监控中心报表存放目录
dubbo.charts.directory=${ dubbo.jetty.directory}/charts
(9)监控中心数据资料目录
dubbo.statistics.directory=${ user.home}/monitor/statistics
()监控中心日志文件路径
dubbo.log4j.file=logs/dubbo-monitor-simple.log
()监控中心日志记录级别
dubbo.log4j.level=WARN
2、Dubbo提供负载均衡方式
(1)Random,随机,按权重配置随机概率,调用量越大分布越均匀,默认方式。
(2)RounRobin,unlocker源码轮询,按权重设置轮询比例,如果存在比较慢的机器容易在这台机器上请求阻塞较多。
(3)LeastActive,最少活跃调用数,不支持权重,只能根据自动识别的活跃数分配,不能灵活调配。
(4)ConsistenHash,一致性hash,对相同参数的请求路由到一个服务提供者上,如果有类似灰度发布需求可采用。
3、Dubbo过滤器
Dubbo初始化过程加载ClassPath下的META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/三个路径下的com.alibaba.dubbo.rpc.Filter文件。文件内容:
Name=FullClassName,这些类必须实现Filter接口。自定义Filter类:
配置文件在配置过滤器,consumer.xml中:
Dubbo对过滤器的加载过程:
先加载三个路径下的com.alibaba.dubbo.rpc.Filter文件里面的键值对,key为过滤器名称,value为过滤器的类的全限定名(这个类必须实现Dubbo中的Filter接口)。自定义的类中@Active注解是过滤器设定的全局基本属性。Spring在加载consumer.xml文件时,通过dubbo:consumerfilter="xxx"id="xxx"retrries="0"这个配置指定消费者端要加载的过滤器,通过filter属性指定过滤器名称。@Activate注解-自动激活,group属性是表示匹配了对应的角色才被加载,value表示表明过滤条件,不写则表示所有条件都会被加载,写了则只有dubboURL中包含该参数名且参数值不为空才被加载,这个参数会以dubbo协议的一个参数K-V对传到Provider。
4、Dubbo的Provider配置
5、Dubbo的Consumer配置
1、Dubbo是什么?
Dubbo是阿里巴巴开源的基于Java的高性能RPC分布式框架。
2、为什么使用Dubbo?
很多公司都在使用,经过很多线上的考验,内部使用了Netty,Zookeeper,保证了高性能可用性。
使用Dubbo可以将核心业务抽取出来,worklog 源码作为独立的服务,逐渐形成稳定的服务中心,可以提高业务复用灵活性扩展,使前端应用能快速的响应对边的市场需求。分布式架构可以承受更大规模的并发流量。
Dubbo的服务治理图:
3、Dubbo和SpringCloud的区别
两个没有关联,但是非要说区别,有如下几点:
(1)通信方式不同,Dubbo使用RPC通信,SpringCloud使用HTTPRestful方式
(2)组成部分不同
4、Dubbo支持的协议
dubbo://?(推荐);rmi://;hessian://;.weidian.dubbo.IMyDemo"version="1.0"id="myDemo"url="dubbo://.0.0.1:/"/dubbo:reference
、Dubbo多协议
Dubbo允许配置多协议,在不同服务器上支持不同协议,或者同一服务支持多种协议。
、当一个服务有多种实现时怎么做?
当一个接口有多种是现实,可以用group属性来分组,服务提供方和消费方都指定同一个group即可。
、兼容旧版本
使用版本号过度,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。
、Dubbo可以缓存吗?
Dubbo提供声明式缓存,用于加速热门数据的访问速度,以减少用户加缓存的工作量。
、Dubbo服务之间的调用时阻塞的吗?
默认是同步等待结果阻塞的,支持异步调用。Dubbo是基于NIO的非阻塞实现并行调用的,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个Future对象。
、Dubbo不支持分布式事务
、Dubbo必须依赖的包
Dubbo必须依赖JDK,其他为可选。
、Dubbo使用过程中的问题
Dubbo的设计目的是为了满足高并发小数据量的rpc请求,在大数据量下性能表现不是很好,建议使用rmi或.alibaba.boot/groupId
artifactIddubbo-spring-boot-starter/artifactIdversion0.1.0/version/dependency
!----
dependency
groupIdcom.tec/groupIdartifactIdzkclient/artifactIdversion0./version/dependency
(2)配置dubbo
##Dubbo服务提供者配置
spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://.0.0.1:
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=
spring.dubbo.scan=org.spring.springboot.dubbo
##Dubbo服务消费者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://.0.0.1:
spring.dubbo.scan=org.spring.springboot.dubbo
Dubbo分布式服务框架介绍随着业务的发展、用户量的增长、系统并发访问需求越来越大,系统数量增多,调用依赖关系也变得复杂,为了确保系统高可用、高并发的要求,系统的架构也从单体时代慢慢迁移至服务SOA时代,根据不同服务对系统资源的要求不同,我们可以更合理的配置系统资源,使系统资源利用率最大化。而Dubbo则是SOA服务化治理方案的一个核心框架。
Dubbo作为阿里巴巴内部的SOA服务化治理方案的核心框架,在年时已经每天为+个服务提供3,,,+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。Dubbo自年开源后,已被许多肢启知非阿里系公司使用,其中既有当当网、网易考拉等互联网公司,也有中国人寿、青岛海尔等传统企业。
Dubbo是一个高性能服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,使得应用可通过高性能RPC实现服务的输出和输入功能,和Spring框架可以无缝集成。
作为一个分布式服务框架,以及SOA治理方案,Dubbo其功能主要包括:
Dubbo最大的特点是按照分层架构思维构建应用服务,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
Dubbo包含远程通讯、服务集群和服务发现与注册三个核心部分。提供透明化的远程方法调用,实现像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。同时具备软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。可以实现服旁则务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
Dubbo服务组件调用关秕说明:
Dubbo框架设计一共划分了个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为历消双方都用到的接口。
下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:
从上图可以看出,Dubbo对于服务提供方和服务消费方,从框架的层中分别提供了各自需要关心和扩展的接口,构建整个服务生态系统(服务提供方和服务消费方本身就是一个以服务为中心的)。
根据官方提供的,对于上述各层之间关系的描述,如下所示:
说说Dubbo的分层?
从?的范围来说,dubbo分为三层,
business业务逻辑层由我们?来提供接?和实现还有?些配置信息;
RPC层就是真正的RPC调?的核?层,封装整个RPC的调?过程、负载均衡、集群容错、代理,
remoting则是对?络传输协议和数据转换的封装。划分到更细的层?,就是图中的层模式,整个分层依赖由上?下,除开business业务逻辑之外,其他的?层都是SPI机制。
如何更好地学习dubbo源代码一、Dubbo整体架构
1、Dubbo与Spring的整合
Dubbo在使用上可以做到非常简单,不管是Provider还是Consumer都可以通过Spring的配置文件进行配置,配置完之后,就可以像使用
springbean一样进行服务暴露和调用了,完全看不到dubbo
api的存在。这是因为dubbo使用了spring提供的可扩展Schema自定义配置支持。在spring配置文件中,可以像、这样进行配置。
META-INF下的spring.handlers文件中指定了dubbo的xml解析类:DubboNamespaceHandler。像前面的被解
析成ServiceConfig,被解析成ReferenceConfig等等。
2、jdkspi扩展
由于Dubbo是开源框架,必须要提供很多的可扩展点。Dubbo是通过扩展jdk
spi机制来实现可扩展的。具体来说,就是在META-INF目录下,放置文件名为接口全称,文件中为key、value键值对,value为具体实现类
的全类名,key为标志值。由于dubbo使用了url总线的设计,即很多参数通过URL对象来传递,在实际中,具唯睁体要用到哪个值,可以通过url中的参
数值来指定。
Dubbo对spi的扩展是通过ExtensionLoader来实现的,查看ExtensionLoader的源码,可以看到Dubbo对jdkspi做了三个方面的扩展:
(1)jdkspi仅仅通过接口类名获取所有实现,而ExtensionLoader则通过接口类名和key值获取一个实现;
(2)Adaptive实现,就是生成一个代理类,这样搭燃就可以根据实际调用时的一些参数动态决定要调用的类了。
(3)自动包装实现,这种实现的类一般是自动激活的,常用于包装类,比如Protocol的两个实现类:ProtocolFilterWrapper、ProtocolListenerWrapper。
3、url总线设计
Dubbo为了使得各层解耦,采用了url总线的设计。我们通常的设计会把层与层之间的交互参数做成Model,这样层与层之间沟通成本比较大,扩展起来
也比较麻烦。因此,Dubbo把各层之间的通信都采用url的形式。比如,注册中心启动时,参数的url为:
registry://0.0.0.0:?codec=registrytransporter=netty
这就表示当前是注册中知山虚心,绑定到所有ip,端口是,解析器类型是registry,使用的底层网络通信框架是netty。
二、Dubbo启动过程
Dubbo分为注册中心、服务提供者(provider)、服务消费者(consumer)三个部分。
1、注册中心启动过程
注册中心的启动过程,主要看两个类:RegistrySynchronizer、RegistryReceiver,两个类的初始化方法都是start。
RegistrySynchronizer的start方法:
(1)把所有配置信息load到内存;
(2)把当前注册中心信息保存到数据库;
(3)启动5个定时器。
5个定时器的功能是:
(1)AutoRedirectTask,自动重定向定时器。默认1小时运行1次。如果当前注册中心的连接数高于平均值的1.2倍,则将多出来的连接数重定向到其他注册中心上,以达到注册中心集群的连接数均衡。
(2)DirtyCheckTask,脏数据检查定时器。作用是:分别检查缓存provider、数据库provider、缓存consumer、数据库
consumer的数据,清除脏数据;清理不存活的provider和consumer数据;对于缓存中的存在的provider或consumer而数
据库不存在,重新注册和订阅。
(3)ChangedClearTask,changes变更表的定时清理任务。作用是读取changes表,清除过期数据。
(4)AlivedCheckTask,注册中心存活状态定时检查,会定时更新registries表的expire字段,用以判断注册中心的存活状态。如果有新的注册中心,发送同步消息,将当前所有注册中心的地址通知到所有客户端。
(5)ChangedCheckTask,变更检查定时器。检查changes表的变更,检查类型包括:参数覆盖变更、路由变更、服务消费者变更、权重变更、负载均衡变更。
RegistryReceiver的start方法:启动注册中心服务。默认使用netty框架,绑定本机的端口。最后启动服务的过
docker jetty å¯å¨ war
æ建tomcatçåºç¡éåã
1.ä¸è½½å¹¶ä¸ä¼ tomcatå°linuxæå¡å¨ãå¨è¿éæ使ç¨çtomcatçæ¬æ¯8.5.ï¼ä¸ä¼ å解åæ件并éå½åã2.ç¼åDockerfileãè¿é使ç¨çæ¯æä¹åæ建çjdkæå°éåï¼è¿éä¸å¨èµè¿°ï¼å ·ä½æ¥çæ建æå°jdkDockeréåè¿ç¯æç« ã3æ建éåãéåå称为ï¼simon/base-tomcatï¼éåTAG为ï¼1.0ã4å¯å¨å®¹å¨ã
camel-docker-jettyï¼å¨docker容å¨ä¸æ¼ç¤ºéªé©¼æäºç¤ºä¾çç®å项ç®-æºç CamelRouterWAR项ç®-使ç¨ä¸ç¹ç¹Docker该项ç®å æ¬ä¸ä¸ªä½ä¸ºWARç示ä¾è·¯ç±ã
四种方法实现http服务
当面临非Springboot项目中实现HTTP服务的需求时,有四种方法可供选择:基于Tomcat、Jetty、JdkHttp和Netty。这些内嵌web容器各有特色,适合不同的场景和性能需求。
Tomcat作为常见的选择,可通过添加Maven坐标并实现初始化代码来实现,如JdkSimpleDispatchServlet所示。它内置了Servlet支持,适用于基础需求。
Jetty与Tomcat类似,通过启动方法启动,其依赖相对简单。它的服务初始化代码简洁,对于Web支持同样较为全面。
Netty以其高性能脱颖而出,尤其适合高吞吐量应用。其pom依赖和启动方式都体现了其内置http编解码和协议支持的便利性。
最后,对于不依赖第三方的选项,JDK8内置的HttpServer提供了一种简单直接的方法。需下载rt包源码并在项目中配置,初始化服务的过程相对直接。
总的来说,选择哪种方法取决于具体项目的需求,如对Servlet规范的支持、性能要求以及对第三方依赖的考虑。每个选项都有其独特的优势,值得开发者根据实际情况灵活运用。
ç®è¿°ä¸ä¸Javaä¸çweb容å¨ï¼ä¸¾å 个ä¾åä¹è¡
ç®åå¸åºä¸å¸¸ç¨çå¼æºJava Web容å¨æTomcatãResinåJettyãå ¶ä¸Resinä»V3.0åéè¦è´ä¹°æè½ç¨äºåä¸ç®çï¼èå ¶ä»ä¸¤ç§åæ¯çº¯å¼æºçãå¯ä»¥åå«ä»ä»ä»¬çç½ç«ä¸ä¸è½½ææ°çäºè¿å¶å åæºä»£ç ã
ä½ä¸ºWeb容å¨ï¼éè¦æ¿åè¾é«ç访é®éï¼è½å¤åæ¶ååºä¸åç¨æ·ç请æ±ï¼è½å¤å¨æ¶å£ç¯å¢ä¸ä¿æè¾é«ç稳å®æ§åå¥å£®æ§ãå¨HTTPæå¡å¨é¢åï¼Apache HTTPDçæçæ¯æé«çï¼ä¹æ¯æ为稳å®çï¼ä½å®åªè½å¤çéæ页é¢ç请æ±ï¼å¦æéè¦æ¯æå¨æ页é¢è¯·æ±ï¼åå¿ é¡»å®è£ ç¸åºçæ件ï¼æ¯å¦mod_perlå¯ä»¥å¤çPerlèæ¬ï¼mod_pythonå¯ä»¥å¤çPythonèæ¬ã
ä¸é¢ä»ç»çä¸ä¸Web容å¨ï¼é½æ¯ä½¿ç¨Javaç¼åçHTTPæå¡å¨ï¼å½ç¶ä»ä»¬é½å¯ä»¥åµå°Apacheä¸ä½¿ç¨ï¼ä¹å¯ä»¥ç¬ç«ä½¿ç¨ãåæå®ä»¬å¤ç客æ·è¯·æ±çæ¹æ³æå©äºäºè§£Javaå¤çº¿ç¨å线ç¨æ± çå®ç°æ¹æ³ï¼ä¸ºè®¾è®¡å¼ºå¤§çå¤çº¿ç¨æå¡å¨æ好åºç¡ã
Tomcatæ¯ä½¿ç¨æ广çJava Web容å¨ï¼åè½å¼ºå¤§ï¼å¯æ©å±æ§å¼ºãææ°çæ¬çTomcatï¼5.5.ï¼ä¸ºäºæé«ååºé度åæçï¼ä½¿ç¨äºApache Portable Runtimeï¼APRï¼ä½ä¸ºæåºå±ï¼ä½¿ç¨äºAPRä¸å å«Socketãç¼å²æ± çå¤ç§ææ¯ï¼æ§è½ä¹æé«äºãAPRä¹æ¯Apache HTTPDçæåºå±ãå¯æ³èç¥ï¼åå±äºASFï¼Apache Software Foundationï¼ä¸çæåï¼äºè¡¥äºç¨çæ åµè¿æ¯å¾å¤çï¼è½ç¶ä½¿ç¨äºä¸åçå¼åè¯è¨ã
Tomcat ç线ç¨æ± ä½äºtomcat-util.jaræ件ä¸ï¼å å«äºä¸¤ç§çº¿ç¨æ± æ¹æ¡ãæ¹æ¡ä¸ï¼ä½¿ç¨APRçPoolææ¯ï¼ä½¿ç¨äºJNIï¼æ¹æ¡äºï¼ä½¿ç¨Javaå®ç°çThreadPoolãè¿éä»ç»çæ¯ç¬¬äºç§ãå¦ææ³äºè§£APRçPoolææ¯ï¼å¯ä»¥æ¥çAPRçæºä»£ç ã
ThreadPoolé»è®¤å建äº5个线ç¨ï¼ä¿åå¨ä¸ä¸ªç»´ç线ç¨æ°ç»ä¸ï¼å建æ¶å°±å¯å¨äºè¿äºçº¿ç¨ï¼å½ç¶å¨æ²¡æ请æ±æ¶ï¼å®ä»¬é½å¤çâçå¾ âç¶æï¼å ¶å®å°±æ¯ä¸ä¸ªwhile循ç¯ï¼ä¸åççå¾ notifyï¼ãå¦ææ请æ±æ¶ï¼ç©ºé²çº¿ç¨ä¼è¢«å¤éæ§è¡ç¨æ·ç请æ±ã
å ·ä½ç请æ±è¿ç¨æ¯ï¼ æå¡å¯å¨æ¶ï¼å建ä¸ä¸ªä¸ç»´çº¿ç¨æ°ç»ï¼maxThreadï¼ä¸ªï¼ï¼å¹¶å建空é²çº¿ç¨(minSpareThreadsï¼5个)éæ¶çå¾ ç¨æ·è¯·æ±ã å½æç¨æ·è¯·æ±æ¶ï¼è°ç¨ threadpool.runIt(ThreadPoolRunnable)æ¹æ³ï¼å°ä¸ä¸ªéè¦æ§è¡çå®ä¾ä¼ ç»ThreadPoolä¸ãå ¶ä¸ç¨æ·éè¦æ§è¡çå®ä¾å¿ é¡»å®ç°ThreadPoolRunnableæ¥å£ã ThreadPoolé¦å æ¥æ¾ç©ºé²ç线ç¨ï¼å¦ææåç¨å®è¿è¡è¦æ§è¡ThreadPoolRunnableï¼å¦æ没æ空é²çº¿ç¨å¹¶ä¸æ²¡æè¶ è¿maxThreadsï¼å°±ä¸æ¬¡æ§å建minSpareThreads个空é²çº¿ç¨ï¼å¦æå·²ç»è¶ è¿äºmaxThreadsäºï¼å°±çå¾ ç©ºé²çº¿ç¨äºãæ»ä¹ï¼è¦æ¾å°ç©ºé²ç线ç¨ï¼ä»¥ä¾¿ç¨å®æ§è¡å®ä¾ãæ¾å°åï¼å°è¯¥çº¿ç¨ä»çº¿ç¨æ°ç»ä¸ç§»èµ°ã æ¥çå¤éå·²ç»æ¾å°ç空é²çº¿ç¨ï¼ç¨å®è¿è¡æ§è¡å®ä¾ï¼ThreadPoolRunnableï¼ã è¿è¡å®ThreadPoolRunnableåï¼å°±å°è¯¥çº¿ç¨éæ°æ¾å°çº¿ç¨æ°ç»ä¸ï¼ä½ä¸ºç©ºé²çº¿ç¨ä¾åç»ä½¿ç¨ã
ç±æ¤å¯ä»¥çåºï¼Tomcatç线ç¨æ± å®ç°æ¯æ¯è¾ç®åçï¼ThreadPool.javaä¹åªæè¡ä»£ç ãç¨ä¸ä¸ªä¸ç»´æ°ç»ä¿å空é²ç线ç¨ï¼æ¯æ¬¡ä»¥ä¸ä¸ªè¾å°æ¥ä¼ï¼5个ï¼å建空é²çº¿ç¨å¹¶æ¾å°çº¿ç¨æ± ä¸ã使ç¨æ¶ä»æ°ç»ä¸ç§»èµ°ç©ºé²ç线ç¨ï¼ç¨å®åï¼åâå½è¿âç»çº¿ç¨æ± ã