引用:http://blog.csdn.net/platformer/article/details/7175054
首先虽然这个mod_jk已经过时,但还是放出来大家一起学习一下,文章主要分三部分内容:
1.第一部分:说明主要配置过程
2.第二部分:贴出我的httpd.conf文件
3.第三部分:对mod_jk代码讲解(来源百度)
第一部分:配置
1. 准备环境:
操作系统:windows7
httpd-2.2.21-win32-x86-no_ssl.msi
apache-tomcat-6.0.7
apache-tomcat-5.0.7
tomcat-connectors-1.2.32-windows-i386-httpd-2.2.x
jdk1.5
2. 下载APACHE
这里下载的是APACHE2.2.21版本
3. 下载JK(Tomcat Connector)
Jk是apache和tomcat的连接器,也可以做负载均衡器,主要是apache通过jk找到tomcat。
下载地址:http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/windows/
Jk的版本要与apache的版本对应如:mod_jk-1.2.32-httpd-2.2.x.zip其匹配的Apache为2.2.版本以上可用
4. 下载TOMCAT
apache-tomcat-6.0.7.rar
5. 配置修改过程
1) Apache配置
将Tomcat Connector文件mod_jk.so拷贝到Apache安装目录的modules目录下。
在Apache安装目录下找到conf/httpd.conf文件,使用文本编辑器打开:
伪静态修改
将注释放开
找到AllowOverride None 将其修改为 All 内容如下:
- <Directory />
- Options FollowSymLinks
- AllowOverride All
- Order deny,allow
- Deny from all
- </Directory>
Tomcat Connector关联项增加
在LoadModules末尾处增加一下内容:
- #加载mod_jk连接
- LoadModule jk_module modules/mod_jk.so
- ### 配置 mod_jk
- JkWorkersFile "conf\workers.properties" #加载集群中的workers
- #此处是指定分配给tomcat的请求 例如*.do *.jsp
- JkMount /*.jsp controller
- JkLogFile logs/mod_jk.log #指定jk的日志输出文件
- JkLogLevel warn #指定日志级别
- 找到IfModule dir_module 修改默认访问地址,需要根据具体项目实际情况填写,我这里使用的是index.jsp 修改如下:
- <IfModule dir_module>
- DirectoryIndex index.jsp
- </IfModule>
- 找到Virtual hosts 去掉虚拟主机注释
- # Virtual hosts
- #Include conf/extra/httpd-vhosts.conf 将 “#”去掉
- Include conf/extra/httpd-vhosts.conf
- 加载代理(暂时未去掉)
- #LoadModule proxy_module modules/mod_proxy.so
- #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
- #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
- #LoadModule proxy_connect_module modules/mod_proxy_connect.so
- #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
2) Tomcat Connector配置
在Apache配置目录Apache2.2\conf创建workers.properties配置文件,该文件主要用于配置Apache与Tomcat的集成要用到的Tomcat实例和负载均衡分发控制器。
Workers.properties文件放置一下内容;
- #下面是分发控制器 注意不要放tomcat实例
- worker.list=lbcontroller
- #Tomcat1实例配置 这里要和Tomcat配置文件Service.xml的jvmRoute保持一致
- worker.test1.host=localhost
- worker.test1.port=8009
- worker.test1.type=ajp13
- #分发权重 值越大负载越大
- worker.tomcat1.lbfactor=1
- #Tomcat2实例配置
- worker.test2.host=localhost
- worker.test2.port=9009
- worker.test2.type=ajp13
- #分发权重 值越大负载越大
- worker.tomcat2.lbfactor=1
- #负载均衡分发控制器
- worker.lbcontroller.type=lb
- worker.lbcontroller.balance_workers=test1,test2
Tomcat配置文件Service.xml主要注意两个地方,一个是Engine节点需要增加节点标识jvmRoute,一个是将原本注释掉的Session复制节点改为有效。具体如下:
- <!--jvmRoute在各个Tomcat配置中不能重复且要与worker.properties文件中的名称一致-->
- <Engine name="Catalina" defaultHost="localhost" jvmRoute="test1">
- <!--session复制内容-->
- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
- channelSendOptions="8">
- <Manager className="org.apache.catalina.ha.session.DeltaManager"
- expireSessionsOnShutdown="false"
- notifyListenersOnReplication="true"/>
- <Channel className="org.apache.catalina.tribes.group.GroupChannel">
- <Membership className="org.apache.catalina.tribes.membership.McastService"
- address="228.0.0.4"
- port="45564"
- frequency="500"
- dropTime="3000"/>
- <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
- address="auto"
- port="4000"
- autoBind="100"
- selectorTimeout="5000"
- maxThreads="6"/>
- <!-- timeout="60000"-->
- <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
- <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
- </Sender>
- <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
- <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
- <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
- </Channel>
- <!--过滤的文件-->
- <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
- <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
- <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
- tempDir="/tmp/war-temp/"
- deployDir="/tmp/war-deploy/"
- watchDir="/tmp/war-listen/"
- watchEnabled="false"/>
- <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
- <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
- </Cluster>
- <!--session复制内容-->
<!—Host节点增加一下内容表示站点根路径-->
- <Context path="/sc" docBase="." privileged="true"/>
我们分别将两个Tomcat配置文件中的jvmRoute设置为tomcat1、tomcat2,Server节点 端口分别配置为8005和9005, Connector节点端口分别配置为8080和9090,AJPConnector端口分别配置为8009和9009,Connector端口配置参照单主机多站点场景。请注意两个Tomcat配置文件Host节点的域名配置必须一样,Server.xml中的jvmRoute名称必须和worker.properties中的tomcat实例名称一致,不然无法实现session_stricky。
- *****************************************************************************
- 如果需要实现session 复制 需要在Tomcat 下conf/web.xml 中加上<distributable/>
- <?xml version="1.0" encoding="ISO-8859-1"?>
- 省略N多代码。。。。。。
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- <distributable/>
- </web-app>
- *****************************************************************************
第二部分:httpd.conf文件
- #
- # This is the main Apache HTTP server configuration file. It contains the
- # configuration directives that give the server its instructions.
- # See <URL:http://httpd.apache.org/docs/2.2> for detailed information.
- # In particular, see
- # <URL:http://httpd.apache.org/docs/2.2/mod/directives.html>
- # for a discussion of each configuration directive.
- #
- # Do NOT simply read the instructions in here without understanding
- # what they do. They're here only as hints or reminders. If you are unsure
- # consult the online docs. You have been warned.
- #
- # Configuration and logfile names: If the filenames you specify for many
- # of the server's control files begin with "/" (or "drive:/" for Win32), the
- # server will use that explicit path. If the filenames do *not* begin
- # with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
- # with ServerRoot set to "D:/Program Files/Apache Software Foundation/Apache2.2" will be interpreted by the
- # server as "D:/Program Files/Apache Software Foundation/Apache2.2/logs/foo.log".
- #
- # NOTE: Where filenames are specified, you must use forward slashes
- # instead of backslashes (e.g., "c:/apache" instead of "c:\apache").
- # If a drive letter is omitted, the drive on which httpd.exe is located
- # will be used by default. It is recommended that you always supply
- # an explicit drive letter in absolute paths to avoid confusion.
- #
- # ServerRoot: The top of the directory tree under which the server's
- # configuration, error, and log files are kept.
- #
- # Do not add a slash at the end of the directory path. If you point
- # ServerRoot at a non-local disk, be sure to point the LockFile directive
- # at a local disk. If you wish to share the same ServerRoot for multiple
- # httpd daemons, you will need to change at least LockFile and PidFile.
- #
- ServerRoot "D:/Program Files/Apache Software Foundation/Apache2.2"
- #
- # Listen: Allows you to bind Apache to specific IP addresses and/or
- # ports, instead of the default. See also the <VirtualHost>
- # directive.
- #
- # Change this to Listen on specific IP addresses as shown below to
- # prevent Apache from glomming onto all bound IP addresses.
- #
- #Listen 12.34.56.78:80
- Listen 8080
- #
- # Dynamic Shared Object (DSO) Support
- #
- # To be able to use the functionality of a module which was built as a DSO you
- # have to place corresponding `LoadModule' lines at this location so the
- # directives contained in it are actually available _before_ they are used.
- # Statically compiled modules (those listed by `httpd -l') do not need
- # to be loaded here.
- #
- # Example:
- # LoadModule foo_module modules/mod_foo.so
- #
- LoadModule actions_module modules/mod_actions.so
- LoadModule alias_module modules/mod_alias.so
- LoadModule asis_module modules/mod_asis.so
- LoadModule auth_basic_module modules/mod_auth_basic.so
- #LoadModule auth_digest_module modules/mod_auth_digest.so
- #LoadModule authn_alias_module modules/mod_authn_alias.so
- #LoadModule authn_anon_module modules/mod_authn_anon.so
- #LoadModule authn_dbd_module modules/mod_authn_dbd.so
- #LoadModule authn_dbm_module modules/mod_authn_dbm.so
- LoadModule authn_default_module modules/mod_authn_default.so
- LoadModule authn_file_module modules/mod_authn_file.so
- #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
- #LoadModule authz_dbm_module modules/mod_authz_dbm.so
- LoadModule authz_default_module modules/mod_authz_default.so
- LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
- LoadModule authz_host_module modules/mod_authz_host.so
- #LoadModule authz_owner_module modules/mod_authz_owner.so
- LoadModule authz_user_module modules/mod_authz_user.so
- LoadModule autoindex_module modules/mod_autoindex.so
- #LoadModule cache_module modules/mod_cache.so
- #LoadModule cern_meta_module modules/mod_cern_meta.so
- LoadModule cgi_module modules/mod_cgi.so
- #LoadModule charset_lite_module modules/mod_charset_lite.so
- #LoadModule dav_module modules/mod_dav.so
- #LoadModule dav_fs_module modules/mod_dav_fs.so
- #LoadModule dav_lock_module modules/mod_dav_lock.so
- #LoadModule dbd_module modules/mod_dbd.so
- #LoadModule deflate_module modules/mod_deflate.so
- LoadModule dir_module modules/mod_dir.so
- #LoadModule disk_cache_module modules/mod_disk_cache.so
- #LoadModule dumpio_module modules/mod_dumpio.so
- LoadModule env_module modules/mod_env.so
- #LoadModule expires_module modules/mod_expires.so
- #LoadModule ext_filter_module modules/mod_ext_filter.so
- #LoadModule file_cache_module modules/mod_file_cache.so
- #LoadModule filter_module modules/mod_filter.so
- #LoadModule headers_module modules/mod_headers.so
- #LoadModule ident_module modules/mod_ident.so
- #LoadModule imagemap_module modules/mod_imagemap.so
- LoadModule include_module modules/mod_include.so
- #LoadModule info_module modules/mod_info.so
- LoadModule isapi_module modules/mod_isapi.so
- #LoadModule ldap_module modules/mod_ldap.so
- #LoadModule logio_module modules/mod_logio.so
- LoadModule log_config_module modules/mod_log_config.so
- #LoadModule log_forensic_module modules/mod_log_forensic.so
- #LoadModule mem_cache_module modules/mod_mem_cache.so
- LoadModule mime_module modules/mod_mime.so
- #LoadModule mime_magic_module modules/mod_mime_magic.so
- LoadModule negotiation_module modules/mod_negotiation.so
- #LoadModule proxy_module modules/mod_proxy.so
- #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
- #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
- #LoadModule proxy_connect_module modules/mod_proxy_connect.so
- #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
- #LoadModule proxy_http_module modules/mod_proxy_http.so
- #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
- #LoadModule reqtimeout_module modules/mod_reqtimeout.so
- #url伪静态
- LoadModule rewrite_module modules/mod_rewrite.so
- LoadModule setenvif_module modules/mod_setenvif.so
- #LoadModule speling_module modules/mod_speling.so
- #LoadModule ssl_module modules/mod_ssl.so
- #LoadModule status_module modules/mod_status.so
- #LoadModule substitute_module modules/mod_substitute.so
- #LoadModule unique_id_module modules/mod_unique_id.so
- #LoadModule userdir_module modules/mod_userdir.so
- #LoadModule usertrack_module modules/mod_usertrack.so
- #LoadModule version_module modules/mod_version.so
- #LoadModule vhost_alias_module modules/mod_vhost_alias.so
- #加载mod_jk连接
- LoadModule jk_module modules/mod_jk.so
- #加载集群中的workers
- JkWorkersFile "conf/workers.properties"
- #此处是指定分配给tomcat的请求 例如*.do *.jsp
- JkMount /*.jsp lbcontroller
- #指定jk的日志输出文件
- JkLogFile "logs/mod_jk.log"
- #指定日志级别
- JkLogLevel warn
- <IfModule !mpm_netware_module>
- <IfModule !mpm_winnt_module>
- #
- # If you wish httpd to run as a different user or group, you must run
- # httpd as root initially and it will switch.
- #
- # User/Group: The name (or #number) of the user/group to run httpd as.
- # It is usually good practice to create a dedicated user and group for
- # running httpd, as with most system services.
- #
- User daemon
- Group daemon
- </IfModule>
- </IfModule>
- # 'Main' server configuration
- #
- # The directives in this section set up the values used by the 'main'
- # server, which responds to any requests that aren't handled by a
- # <VirtualHost> definition. These values also provide defaults for
- # any <VirtualHost> containers you may define later in the file.
- #
- # All of these directives may appear inside <VirtualHost> containers,
- # in which case these default settings will be overridden for the
- # virtual host being defined.
- #
- #
- # ServerAdmin: Your address, where problems with the server should be
- # e-mailed. This address appears on some server-generated pages, such
- # as error documents. e.g. admin@your-domain.com
- #
- ServerAdmin localhost
- #
- # ServerName gives the name and port that the server uses to identify itself.
- # This can often be determined automatically, but we recommend you specify
- # it explicitly to prevent problems during startup.
- #
- # If your host doesn't have a registered DNS name, enter its IP address here.
- #
- ServerName localhost:8080
- #
- # DocumentRoot: The directory out of which you will serve your
- # documents. By default, all requests are taken from this directory, but
- # symbolic links and aliases may be used to point to other locations.
- #
- DocumentRoot "D:/work/work_bz/test/WebRoot"
- #
- # Each directory to which Apache has access can be configured with respect
- # to which services and features are allowed and/or disabled in that
- # directory (and its subdirectories).
- #
- # First, we configure the "default" to be a very restrictive set of
- # features.
- # 默认为 AllowOverride None
- <Directory />
- Options FollowSymLinks
- AllowOverride All
- #Order deny,allow
- #Deny from all
- Order allow,deny
- Allow from all
- Satisfy all
- </Directory>
- #首次访问页面
- <IfModule dir_module>
- DirectoryIndex index.jsp
- </IfModule>
- #
- # The following lines prevent .htaccess and .htpasswd files from being
- # viewed by Web clients.
- #
- <FilesMatch "^\.ht">
- Order allow,deny
- Deny from all
- Satisfy All
- </FilesMatch>
- #
- # ErrorLog: The location of the error log file.
- # If you do not specify an ErrorLog directive within a <VirtualHost>
- # container, error messages relating to that virtual host will be
- # logged here. If you *do* define an error logfile for a <VirtualHost>
- # container, that host's errors will be logged there and not here.
- #
- ErrorLog "logs/error.log"
- #
- # LogLevel: Control the number of messages logged to the error_log.
- # Possible values include: debug, info, notice, warn, error, crit,
- # alert, emerg.
- #
- LogLevel warn
- <IfModule log_config_module>
- #
- # The following directives define some format nicknames for use with
- # a CustomLog directive (see below).
- #
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
- LogFormat "%h %l %u %t \"%r\" %>s %b" common
- <IfModule logio_module>
- # You need to enable mod_logio.c to use %I and %O
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
- </IfModule>
- #
- # The location and format of the access logfile (Common Logfile Format).
- # If you do not define any access logfiles within a <VirtualHost>
- # container, they will be logged here. Contrariwise, if you *do*
- # define per-<VirtualHost> access logfiles, transactions will be
- # logged therein and *not* in this file.
- #
- CustomLog "logs/access.log" common
- #
- # If you prefer a logfile with access, agent, and referer information
- # (Combined Logfile Format) you can use the following directive.
- #
- #CustomLog "logs/access.log" combined
- </IfModule>
- <IfModule alias_module>
- #
- # Redirect: Allows you to tell clients about documents that used to
- # exist in your server's namespace, but do not anymore. The client
- # will make a new request for the document at its new location.
- # Example:
- # Redirect permanent /foo http://192.168.12.242/bar
- #
- # Alias: Maps web paths into filesystem paths and is used to
- # access content that does not live under the DocumentRoot.
- # Example:
- # Alias /webpath /full/filesystem/path
- #
- # If you include a trailing / on /webpath then the server will
- # require it to be present in the URL. You will also likely
- # need to provide a <Directory> section to allow access to
- # the filesystem path.
- #
- # ScriptAlias: This controls which directories contain server scripts.
- # ScriptAliases are essentially the same as Aliases, except that
- # documents in the target directory are treated as applications and
- # run by the server when requested rather than as documents sent to the
- # client. The same rules about trailing "/" apply to ScriptAlias
- # directives as to Alias.
- #
- ScriptAlias /cgi-bin/ "D:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"
- </IfModule>
- <IfModule cgid_module>
- #
- # ScriptSock: On threaded servers, designate the path to the UNIX
- # socket used to communicate with the CGI daemon of mod_cgid.
- #
- #Scriptsock logs/cgisock
- </IfModule>
- #
- # "D:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin" should be changed to whatever your ScriptAliased
- # CGI directory exists, if you have that configured.
- #
- <Directory "D:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin">
- AllowOverride None
- Options None
- Order allow,deny
- Allow from all
- </Directory>
- #
- # DefaultType: the default MIME type the server will use for a document
- # if it cannot otherwise determine one, such as from filename extensions.
- # If your server contains mostly text or HTML documents, "text/plain" is
- # a good value. If most of your content is binary, such as applications
- # or images, you may want to use "application/octet-stream" instead to
- # keep browsers from trying to display binary files as though they are
- # text.
- #
- DefaultType text/plain
- <IfModule mime_module>
- #
- # TypesConfig points to the file containing the list of mappings from
- # filename extension to MIME-type.
- #
- TypesConfig conf/mime.types
- #
- # AddType allows you to add to or override the MIME configuration
- # file specified in TypesConfig for specific file types.
- #
- #AddType application/x-gzip .tgz
- #
- # AddEncoding allows you to have certain browsers uncompress
- # information on the fly. Note: Not all browsers support this.
- #
- #AddEncoding x-compress .Z
- #AddEncoding x-gzip .gz .tgz
- #
- # If the AddEncoding directives above are commented-out, then you
- # probably should define those extensions to indicate media types:
- #
- AddType application/x-compress .Z
- AddType application/x-gzip .gz .tgz
- #
- # AddHandler allows you to map certain file extensions to "handlers":
- # actions unrelated to filetype. These can be either built into the server
- # or added with the Action directive (see below)
- #
- # To use CGI scripts outside of ScriptAliased directories:
- # (You will also need to add "ExecCGI" to the "Options" directive.)
- #
- #AddHandler cgi-script .cgi
- # For type maps (negotiated resources):
- #AddHandler type-map var
- #
- # Filters allow you to process content before it is sent to the client.
- #
- # To parse .shtml files for server-side includes (SSI):
- # (You will also need to add "Includes" to the "Options" directive.)
- #
- #AddType text/html .shtml
- #AddOutputFilter INCLUDES .shtml
- </IfModule>
- #
- # The mod_mime_magic module allows the server to use various hints from the
- # contents of the file itself to determine its type. The MIMEMagicFile
- # directive tells the module where the hint definitions are located.
- #
- #MIMEMagicFile conf/magic
- #
- # Customizable error responses come in three flavors:
- # 1) plain text 2) local redirects 3) external redirects
- #
- # Some examples:
- #ErrorDocument 500 "The server made a boo boo."
- #ErrorDocument 404 /missing.html
- #ErrorDocument 404 "/cgi-bin/missing_handler.pl"
- #ErrorDocument 402 http://192.168.12.242/subscription_info.html
- #
- #
- # MaxRanges: Maximum number of Ranges in a request before
- # returning the entire resource, or 0 for unlimited
- # Default setting is to accept 200 Ranges
- #MaxRanges 0
- #
- # EnableMMAP and EnableSendfile: On systems that support it,
- # memory-mapping or the sendfile syscall is used to deliver
- # files. This usually improves server performance, but must
- # be turned off when serving from networked-mounted
- # filesystems or if support for these functions is otherwise
- # broken on your system.
- #
- #EnableMMAP off
- #EnableSendfile off
- # Supplemental configuration
- #
- # The configuration files in the conf/extra/ directory can be
- # included to add extra features or to modify the default configuration of
- # the server, or you may simply copy their contents here and change as
- # necessary.
- # Server-pool management (MPM specific)修改连接数
- Include conf/extra/httpd-mpm.conf
- # Multi-language error messages
- #Include conf/extra/httpd-multilang-errordoc.conf
- # Fancy directory listings
- #Include conf/extra/httpd-autoindex.conf
- # Language settings
- #Include conf/extra/httpd-languages.conf
- # User home directories
- #Include conf/extra/httpd-userdir.conf
- # Real-time info on requests and configuration
- #Include conf/extra/httpd-info.conf
- # Virtual hosts 虚拟主机 没有域名不需要设置
- #Include conf/extra/httpd-vhosts.conf
- # Local access to the Apache HTTP Server Manual
- #Include conf/extra/httpd-manual.conf
- # Distributed authoring and versioning (WebDAV)
- #Include conf/extra/httpd-dav.conf
- # Various default settings
- #Include conf/extra/httpd-default.conf
- # Secure (SSL/TLS) connections
- #Include conf/extra/httpd-ssl.conf
- #
- # Note: The following must must be present to support
- # starting without SSL on platforms with no /dev/random equivalent
- # but a statically compiled-in mod_ssl.
- #
- <IfModule ssl_module>
- SSLRandomSeed startup builtin
- SSLRandomSeed connect builtin
- </IfModule>
第三部分:mod_jk代码讲解
mod_jk 分析
1 mod_jk模块的总体功能
由于tomcat的HTTP处理部分都由Java所写(5.5.12版本以后出现了native库,用以
提高其I/O和SSL的性能[1]),在高并发的情况下负载较高。而apache对于静态文件的处
理能力比tomcat强,所以tomcat开发组开发了与apache结合使用的mod_jk模块。该协议
由apache作请求代理,将HTTP协议的请求转化为AJP协议包,并传给后端的
tomcat。mod_jk和apache现在普遍使用AJP1.3协议[2]。它是一个二进制格式的协议,比
字符格式的HTTP协议解析速度要快。
除了性能的提升,mod_jk另外的一个作用可以实现apache与tomcat一对多的对应,
使后端tomcat负载均衡。mod_jk也提供apache与tomcat链接情况的监控。
mod_jk模块的典型工作流程是这样的:一个HTTP请求过来,mod_jk模块根据其URI选
择合适的worker来进行处理。如果是lb_worker(负载均衡的worker),就再根据各种条
件选择后台合适的ajp_worker(处理AJP协议的worker)。ajp_worker将HTTP协议的包,
组装成AJP协议格式的包,然后选取一条空闲的链接,发送给后台的tomcat服务器。等到
后台将数据发送过来时,接收并解析AJP协议,重新组装成HTTP协议,然后把结果发送给
客户端。
2 mod_jk模块的框架
2.1 线程
从宏观上来讲,mod_jk由一个watchdog线程和一组worker线程(进程)组成。
watchdog线程是在apache内部新创建的线程,它是一个维护线程。每隔
JkWatchdogInterval的时间(当然,所有worker线程也有一个统一的worker.maintain 时
间,JkWatchdogInterval应该至少大于worker.maintain),它会扫描所有worker线程。
watchdog线程会检查每个worker线程的空闲链接、负载情况、与后端的链接情况,并使共
享内存同步。worker线程是就是一些ajp13,ajp14,jni,lb或status类型的线程,负责
所有实际的工作。
在mod_jk中,线程内(外)的同步均是通过线程锁(pthread_mutex_lock)来实现的。
而进程之间的全局同步,是用文件记录锁(flock或fcntl)来实现。进程间的数据共享是
用这样做的:进程启动时,创建一个JkShmSize 大小的文件,然后mmap到内存,由于各进
程mmap到内存的是相同的镜像,所以可以实现数据的共享,但是写入共享内存时,要做好
互斥。
由于apache的基本处理方式(prefork和worker模式)就是一个线程/进程负责一个
连接,所以mod_jk各线程中对于网络IO处理都是阻塞的。
2.2 worker对象
从具体的worker对象的角度来讲,mod_jk由ajp_worker、jni_worker、lb_worker和
status_worker组成。这些对象参考了设计模式中factory的模型。每类worker都有生产
workers的factory。
在mod_jk中,其中的worker主要在worker.list中列出。其中,lb_worker可以含有
balance_workers,以lb_sub_worker的形式存储于lb_worker中。lb_sub_worker可以是各
种类型的ajp_worker。所以真正工作的ajp_worker既可以“单干”,也可以由lb_worker
来分配任务。这主要取决于URI到底映射到哪个worker上以及该worker是否在
worker.list配置。
lb_worker,lb_sub_worker和ajp_worker一些配置信息都位于其结构体中,而状态信
息或在运行中可变的参数则位于共享内存中的对应结构体中,当然也并不绝对,有些参数是
冗余的。
从正在运行的某个线程的角度上来讲,ajp_worker就是对应了一个线程。
3 从HTTP到AJP的处理流程
由于mod_jk模块是apache的处理模块,本节主要是讲述mod_jk模块从客户端到后端
服务器的处理流程。中间会涉及一些apache模块的一些结构。
3.1 mod_jk模块在apache中的定义
3.1.1 mod_jk定义
/* 这是jk模块的主要定义结构体*/
module AP_MODULE_DECLARE_DATA jk_module = {
STANDARD20_MODULE_STUFF,
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
create_jk_config, /*创建 jk模块的配置结构体*/
merge_jk_config, /* 初始化及合并 jk模块的配置结构体*/
jk_cmds, /* 所有在apahce中的命令及操作函数 */
jk_register_hooks /* 具体的操作函数处理钩子 */
};
3.1.2 mod_jk模块的主要处理函数
/* mod_jk将各处理函数挂到相应的钩子上,钩子实际上就是一些函数指针。针对某个HTTP
请求,这些函数会自上而下执行。*/
static void jk_register_hooks(apr_pool_t * p)
{
/* 该函数在apache读入配置后运行,用以初始化全局互斥锁,jk日志,全局变量的初
始化,以及读入 workers.properties、uriworkermap.properties文件,初始化各worker
的属性,建立worker名称到worker结构体的映射,uri到worker的映射*/
ap_hook_post_config(jk_post_config, NULL, NULL, APR_HOOK_MIDDLE);
/*该函数在apache主进程fork工作子进程后做的初始化工作,主要包括初始化进程内
互斥锁,开启维护线程,读入共享内存*/
ap_hook_child_init(jk_child_init, NULL, NULL, APR_HOOK_MIDDLE);
/* 将mod_jk的URI到真实URI,然后URI到worker的映射翻译过程,用以找到该URI
相应的worker_name */
ap_hook_translate_name(jk_translate, NULL, NULL, APR_HOOK_MIDDLE);
#if (MODULE_MAGIC_NUMBER_MAJOR > 20010808)
/* 绑定那些alias_dir的URI到mod_jk的配置,并找到相应worker_name */
ap_hook_map_to_storage(jk_map_to_storage, NULL, NULL, APR_HOOK_MIDDLE);
/* 这是mod_jk的主要处理函数 */
ap_hook_handler(jk_handler, NULL, NULL, APR_HOOK_MIDDLE);
#endif
}
3.2 jk_handler函数
jk_handler函数是mod_jk的主要处理函数,它负责将HTTP请求从apache发到tomcat,
再从tomcat接受数据,并返回给客户。
它的处理过程如下:
1. 根据前面得到的worker_name,找到相应的jk_worker(其结构体见4.4)。
2. 初始化服务结构体jk_ws_service,主要是针对HTTP服务端的一些设置及函数(服务
的结构体见4.5),与AJP协议关系不大。
3. 调用jk_worker的get_endpoint函数,获取具体的jk_endpoint结构体(函数见
3.3.1和3.4.1,jk_endpoint的结构体定义见4.4)。
4. 调用上述jk_endpoint的service函数。
5. 调用上述jk_endpoint的done函数,结束与tomcat的AJP连接。
6. 根据函数的结果处理各种状态。
7. 释放资源。
3.3 lb_worker的处理函数
3.3.1 lb_worker的get_endpoint
初始化lb_worker的endpoint结构体,挂上其service及done函数。
3.3.2 lb_worker的service函数
它的处理过程如下:
1. 获取共享内存中记录的worker状态。
2. 如果需要绑定sessionID,获取sessionID。
3. 调用get_most_suitable_worker函数,获取相应的lb_sub_worker(也即
ajp_worker)。
4. 调用ajp_worker的get_endpoint函数。
5. 调用上述endpoint的service函数。
6. 调用上述endpoint的done函数。
7. 根据service的返回结果,更新各种记录状态。
3.3.3 get_most_suitable_worker函数
它的处理过程如下:
1. 如果需要绑定sessionID,就根据sessionID找到工作正常的最佳worker。
2. 如果找不到,则调用find_best_worker函数。其处理过程如下:
i. 又调用find_best_byvalue函数。其处理过程如下:按照Round Robin的方式在
本lb_worker中找到第一个不在错误状态、也没有停止、没有disabled 、也不
busy的lb_sub_worker。
ii.如果find_best_byvalue返回错误,说明本lb_worker的lb_sub_worker都处于
非正常工作状态,需要调用find_failover_worker函数,通过
redirect、route、domain指令来进行查找[3]。
3.4 ajp_worker的处理函数
3.4.1 ajp_worker的get_endpoint函数
它的主要功能是:找到与后端tomcat的一个空闲连接。
3.4.2 ajp_worker的ajp_service函数
该函数主要分为 ajp_send_request和and ajp_get_reply两个函数。
它的处理过程如下:
1. 获取共享内存中的状态。
2. 分配AJP请求包、恢复包、POST包的内存。
3. 调用ajp_marshal_into_msgb函数,将HTTP请求包转化为AJP包。
4. 将当前ajp_worker的状态更新。
5. 调用ajp_send_request函数。
6. 如果发送成功,调用ajp_get_reply函数,等待并接受AJP包。
7. 如果成功,更新当前状态。
3.4.2 ajp_worker的ajp_send_request函数
它的处理过程如下:
1. 调用jk_is_socket_connected函数,检查即将发送的socket是否有效。它的检查过
程是运用select函数,等1微妙,如果成功返回说明,该socket的文件描述符至少
在内核中还有效。
2. 如果上一次发送超时,则调用ajp_handle_cping_cpong函数来判断后端连接是否有
效。该函数主要是发出了一个AJP13_CPING_REQUEST类型的AJP包,如果tomcat收
到,应返回一个AJP13_CPONG_REPLY的包。
3. 如果上述的测试都成功,调用ajp_connection_tcp_send_message,发送AJP包。
3.4.3 ajp_worker的ajp_get_reply函数
它的处理过程如下:
1. 调用jk_is_input_event,用select等待接受数据,直到socket有接受数据。
2. 调用ajp_connection_tcp_get_message,接受AJP包,并检查协议头。
3. 调用ajp_process_callback,对该AJP包进行解析处理。其处理过程如下:
i. 如果是JK_AJP13_SEND_HEADERS包,将其解包成HTTP包头。如果没有错误,就调
用jk_ws_service->start_response()函数发送HTTP回复的head。返回
JK_AJP13_SEND_HEADERS。
ii.如果是JK_AJP13_SEND_BODY_CHUNK包,调用jk_ws_service->write发送HTTP回
复的body。返回JK_AJP13_NO_RESPONSE。
iii.如果是JK_AJP13_GET_BODY_CHUNK包,说明还有数据要发送到tomcat,调用
ajp_read_into_msg_buff,继续发送数据。返回JK_AJP13_HAS_RESPONSE。
iv.如果是JK_AJP13_END_RESPONSE包,就说明tomcat的回复已经完成。返回
JK_AJP13_END_RESPONSE。
3.5 jk_ws_service的一些处理函数
3.5.1 jk_ws_service 的 ws_start_response函数
该函数主要是构建HTTP回复包的头部。
3.5.2 jk_ws_service 的 ws_write函数
调用 apache的ap_rwrite函数,发送整个HTTP包。
3.5.3 jk_ws_service 的 ws_read函数
调用apache的ap_get_client_block读入全部的request body数据。
4 mod_jk的主要数据结构
4.1 lb_worker
lb_worker是负载均衡worker。主要负责调配其名下的一些lb_sub_worker 。
- dist/common/jk_lb_worker.h
- struct lb_worker
- {
- /* jk模块通用worker结构体。包含一些回调函数,不同的worker有不同的函数实现
- */
- jk_worker_t worker;
- /* Shared memory worker data */
- jk_shm_lb_worker_t *s;
- char name[JK_SHM_STR_SIZ+1];
- /* Sequence counter starting at 0 and increasing
- * every time we change the config
- */
- volatile unsigned int sequence;
- jk_pool_t p;
- jk_pool_atom_t buf[TINY_POOL_SIZE];
- JK_CRIT_SEC cs;
- /*其名下的workers*/
- lb_sub_worker_t *lb_workers;
- unsigned int num_of_workers;
- int sticky_session;
- int sticky_session_force;
- int recover_wait_time;
- int max_reply_timeouts;
- int retries;
- int retry_interval;
- int lbmethod;
- int lblock;
- int maintain_time;
- unsigned int max_packet_size;
- unsigned int next_offset;
- /* Session cookie */
- char session_cookie[JK_SHM_STR_SIZ+1];
- /* Session path */
- char session_path[JK_SHM_STR_SIZ+1];
- };
- lb_sub_worker是由lb_worker支配的ajp_worker。当然lb_sub_worker有不同的类型。
- 它们的实际类型存储在ajp_worker中。
- dist/common/jk_lb_worker.h
- struct lb_sub_worker
- {
- /* 包含ajp_worker的回调函数及其ajp_worker结构体*/
- jk_worker_t *worker;
- /* Shared memory worker data */
- jk_shm_lb_sub_worker_t *s;
- char name[JK_SHM_STR_SIZ+1];
- /* Sequence counter starting at 0 and increasing
- * every time we change the config
- */
- volatile unsigned int sequence;
- /* route */
- char route[JK_SHM_STR_SIZ+1];
- /* worker domain */
- char domain[JK_SHM_STR_SIZ+1];
- /* worker redirect route */
- char redirect[JK_SHM_STR_SIZ+1];
- /* worker distance */
- int distance;
- /* current activation state (config) of the worker */
- int activation;
- /* Current lb factor */
- int lb_factor;
- /* Current worker index */
- int i;
- /* Current lb reciprocal factor */
- jk_uint64_t lb_mult;
- };
- typedef struct lb_sub_worker lb_sub_worker_t;
- 4.2 ajp_worker
- ajp_worker是具体工作的worker,对应后端一个tomcat应用服务。
- dist/common/jk_ajp_common.c
- struct ajp_worker
- {
- /* 包含ajp_worker的回调函数*/
- jk_worker_t worker;
- /* Shared memory worker data */
- jk_shm_ajp_worker_t *s;
- char name[JK_SHM_STR_SIZ+1];
- /* Sequence counter starting at 0 and increasing
- * every time we change the config
- */
- volatile unsigned int sequence;
- jk_pool_t p;
- jk_pool_atom_t buf[TINY_POOL_SIZE];
- JK_CRIT_SEC cs;
- struct sockaddr_in worker_inet_addr; /* Contains host and port */
- unsigned connect_retry_attempts;
- const char *host;
- int port;
- int maintain_time;
- /*
- * Open connections cache...
- *
- * 1. Critical section object to protect the cache.
- * 2. Cache size.
- * 3. An array of "open" endpoints.
- */
- unsigned int ep_cache_sz;
- unsigned int ep_mincache_sz;
- unsigned int ep_maxcache_sz;
- int cache_acquire_timeout;
- ajp_endpoint_t **ep_cache;
- int proto; /* PROTOCOL USED AJP13/AJP14 */
- jk_login_service_t *login;
- /* Weak secret similar with ajp12, used in ajp13 */
- const char *secret;
- /*
- * Post physical connect handler.
- * AJP14 will set here its login handler
- */
- int (*logon) (ajp_endpoint_t * ae, jk_logger_t *l);
- /*
- * Handle Socket Timeouts
- */
- int socket_timeout;
- int socket_connect_timeout;
- int keepalive;
- int socket_buf;
- /*
- * Handle Cache Timeouts
- */
- int cache_timeout;
- /*
- * Handle Connection/Reply Timeouts
- */
- int connect_timeout; /* connect cping/cpong delay in ms (0 means
- disabled) */
- int reply_timeout; /* reply timeout delay in ms (0 means disabled) */
- int prepost_timeout; /* before sending a request cping/cpong timeout
- delay in ms (0 means disabled) */
- int conn_ping_interval; /* interval for sending keepalive cping packets on
- * unused connection */
- int ping_timeout; /* generic cping/cpong timeout. Used for keepalive
- packets or
- * as default for boolean valued connect and
- prepost timeouts.
- */
- unsigned int ping_mode; /* Ping mode flags (which types of cpings should
- be used) */
- /*
- * Recovery options
- */
- unsigned int recovery_opts;
- /*
- * Public property to enable the number of retry attempts
- * on this worker.
- */
- int retries;
- unsigned int max_packet_size; /* Maximum AJP Packet size */
- int retry_interval; /* Number of milliseconds to sleep before
- doing a retry */
- /*
- * HTTP status that will cause failover (0 means disabled)
- */
- unsigned int http_status_fail_num;
- int http_status_fail[JK_MAX_HTTP_STATUS_FAILS];
- };
- 4.3 status_worker
- status_worker用于产生一些状态的统计信息。
- dist/common/jk_statuc.c
- struct status_worker
- {
- jk_pool_t p;
- jk_pool_atom_t buf[TINY_POOL_SIZE];
- const char *name;
- const char *css;
- const char *ns;
- const char *xmlns;
- const char *doctype;
- const char *prefix;
- int read_only;
- char **user_names;
- unsigned int num_of_users;
- int user_case_insensitive;
- jk_uint32_t good_mask;
- jk_uint32_t bad_mask;
- jk_worker_t worker;
- jk_worker_env_t *we;
- };
- 4.4 jk_worker和 jk_endpoint
- jk_worker是所有worker通用结构体名称, 主要包含的是一些函数指针。它是一个类
- 似java中抽象类的概念,各成员函数在从factory函数生产时初始化。
- dist/common/jk_service.h
- struct jk_worker
- {
- /*
- * A 'this' pointer which is used by the subclasses of this class to
- * point to data/functions which are specific to a given protocol
- * (e.g. ajp12 or ajp13 or ajp14).
- */
- void *worker_private;/* 指向ajp_worker,lb_worker结构体 ...*/
- int type;
- /*
- * For all of the below (except destroy), the first argument is
- * essentially a 'this' pointer.
- */
- /* 先于init函数调用,用于分配各类worker结构体的内存,作必要的初始化
- * Given a worker which is in the process of being created, and a list
- * of configuration options (or 'properties'), check to see if it the
- * options are. This will always be called before the init() method.
- * The init/validate distinction is a bit hazy to me.
- * See jk_ajp13_worker.c/jk_ajp14_worker.c and jk_worker.c-
- >wc_create_worker()
- */
- int (JK_METHOD * validate) (jk_worker_t *w,
- jk_map_t *props,
- jk_worker_env_t *we, jk_logger_t *l);
- /*
- * Update worker either from jk_status or reloading from workers.properties
- */
- int (JK_METHOD * update) (jk_worker_t *w,
- jk_map_t *props,
- jk_worker_env_t *we, jk_logger_t *l);
- /*
- * Do whatever initialization needs to be done to start this worker up.
- * Configuration options are passed in via the props parameter.
- */
- int (JK_METHOD * init) (jk_worker_t *w,
- jk_map_t *props,
- jk_worker_env_t *we, jk_logger_t *l);
- /*
- * Obtain an endpoint to service a particular request. A pointer to
- * the endpoint is stored in pend.
- */
- int (JK_METHOD * get_endpoint) (jk_worker_t *w,
- jk_endpoint_t **pend, jk_logger_t *l);
- /*
- * Shutdown this worker. The first argument is not a 'this' pointer,
- * but rather a pointer to 'this', so that the object can be free'd (I
- * think -- though that doesn't seem to be happening. Hmmm).
- */
- int (JK_METHOD * destroy) (jk_worker_t **w, jk_logger_t *l);
- /*
- * Maintain this worker.
- */
- int (JK_METHOD * maintain) (jk_worker_t *w, time_t now, jk_logger_t *l);
- };
- /* jk_endpoint可以称之为通用终端服务结构体,各类worker可能有自己的endpoint结构
- 体。比如ajp_worker, 该终端是用来做具体工作的,比如发出请求,接收AJP数据等等。如
- 果是lb_worker,该终端是的作用是找出合适ajp_worker, 把任务交给它。* /
- struct jk_endpoint
- {
- jk_uint64_t rd;
- jk_uint64_t wr;
- /*
- * Flag to pass back recoverability status from
- * a load balancer member to the load balancer itself.
- * Depending on the configuration and request status
- * recovery is not allowed.
- */
- int recoverable;
- /*
- * A 'this' pointer which is used by the subclasses of this class to
- * point to data/functions which are specific to a given protocol
- * (e.g. ajp12 or ajp13 or ajp14).
- */
- void *endpoint_private;
- /* 该函数是具体的服务函数
- * Forward a request to the servlet engine. The request is described
- * by the jk_ws_service_t object.
- * is_error is either 0 meaning recoverable or set to
- * the HTTP error code.
- */
- int (JK_METHOD * service) (jk_endpoint_t *e,
- jk_ws_service_t *s,
- jk_logger_t *l, int *is_error);
- /*
- * Called when this particular endpoint has finished processing a
- * request. For some protocols (e.g. ajp12), this frees the memory
- * associated with the endpoint. For others (e.g. ajp13/ajp14), this can
- * return the endpoint to a cache of already opened endpoints.
- *
- * Note that the first argument is *not* a 'this' pointer, but is
- * rather a pointer to a 'this' pointer. This is necessary, because
- * we may need to free this object.
- */
- int (JK_METHOD * done) (jk_endpoint_t **p, jk_logger_t *l);
- };
- 4.5 jk_ws_service
- 该结构体是与apache相关的一些参数或函数,面向HTTP协议,与AJP协议不太相关。
- dist/common/jk_service.h
- struct jk_ws_service
- {
- /*
- * A 'this' pointer which is used by the subclasses of this class to
- * point to data which is specific to a given web server platform
- * (e.g. Apache or IIS).
- */
- void *ws_private;
- /*
- * Provides memory management. All data specific to this request is
- * allocated within this pool, which can then be reclaimed at the end
- * of the request handling cycle.
- *
- * Alive as long as the request is alive.
- */
- jk_pool_t *pool;
- /*
- * CGI Environment needed by servlets
- */
- const char *method;
- const char *protocol;
- char *req_uri;
- const char *remote_addr;
- const char *remote_host;
- const char *remote_user;
- const char *auth_type;
- const char *query_string;
- const char *server_name;
- unsigned server_port;
- char *server_software;
- jk_uint64_t content_length; /* 64 bit integer that represents the content */
- /* length should be 0 if unknown. */
- unsigned is_chunked; /* 1 if content length is unknown (chunked rq) */
- unsigned no_more_chunks; /* 1 if last chunk has been read */
- jk_uint64_t content_read; /* number of bytes read */
- /*
- * SSL information
- *
- * is_ssl - True if request is in ssl connection
- * ssl_cert - If available, base64 ASN.1 encoded client certificates.
- * ssl_cert_len - Length of ssl_cert, 0 if certificates are not available.
- * ssl_cipher - The ssl cipher suite in use.
- * ssl_session - The ssl session string
- *
- * In some servers it is impossible to extract all this information, in this
- * case, we are passing NULL.
- */
- int is_ssl;
- char *ssl_cert;
- unsigned ssl_cert_len;
- char *ssl_cipher;
- char *ssl_session;
- /*
- * SSL extra information for Servlet 2.3 API
- *
- * ssl_key_size - ssl key size in use
- */
- int ssl_key_size;
- /*
- * Headers, names and values.
- */
- char **headers_names; /* Names of the request headers */
- char **headers_values; /* Values of the request headers */
- unsigned num_headers; /* Number of request headers */
- /*
- * Request attributes.
- *
- * These attributes that were extracted from the web server and are
- * sent to Tomcat.
- *
- * The developer should be able to read them from the ServletRequest
- * attributes. Tomcat is required to append org.apache.tomcat. to
- * these attribute names.
- */
- char **attributes_names; /* Names of the request attributes */
- char **attributes_values; /* Values of the request attributes */
- unsigned num_attributes; /* Number of request attributes */
- /*
- * The route is in use when the adapter load balance among
- * several workers. It is the ID of a specific target in the load balance
- * group. We are using this variable to implement target session
- * affinity
- */
- const char *route;
- /* Temp solution for auth. For native1 it'll be sent on each request,
- if an option is present. For native2 it'll be sent with the first
- request. On java side, both cases will work. For tomcat3.2 or
- a version that doesn't support secret - don't set the secret,
- and it'll work.
- */
- const char *secret;
- /*
- * Area to get POST data for fail-over recovery in POST
- */
- jk_msg_buf_t *reco_buf;
- int reco_status;
- /*
- * If set call flush after each write
- */
- int flush_packets;
- /*
- * If set call flush after AJP13_SEND_HEADERS.
- */
- int flush_header;
- /*
- * service extensions
- */
- svc_extension_t extension;
- /*
- * JK_TRUE if response headers have been sent back
- */
- int response_started;
- /*
- * JK_TRUE if response should not be send to the client
- */
- int response_blocked;
- /*
- * HTTP status sent from container.
- */
- int http_response_status;
- /* Uri worker map. Added for virtual host support
- */
- jk_uri_worker_map_t *uw_map;
- /* 下面这些回调函数实现都可以在mod_jk.c找到
- * Callbacks into the web server. For each, the first argument is
- * essentially a 'this' pointer. All return JK_TRUE on success
- * and JK_FALSE on failure.
- */
- /*
- * Send the response headers to the browser.
- */
- int (JK_METHOD * start_response) (jk_ws_service_t *s,
- int status,
- const char *reason,
- const char *const *header_names,
- const char *const *header_values,
- unsigned num_of_headers);
- /*
- * Read a chunk of the request body into a buffer. Attempt to read len
- * bytes into the buffer. Write the number of bytes actually read into
- * actually_read.
- */
- int (JK_METHOD * read) (jk_ws_service_t *s,
- void *buffer,
- unsigned len, unsigned *actually_read);
- /*
- * Write a chunk of response data back to the browser.
- */
- int (JK_METHOD * write) (jk_ws_service_t *s,
- const void *buffer, unsigned len);
- /*
- * Flush a chunk of response data back to the browser.
- */
- void (JK_METHOD * flush) (jk_ws_service_t *s);
- /*
- * Done with sending response back to the browser.
- */
- void (JK_METHOD * done) (jk_ws_service_t *s);
- /*
- * If set do not reuse socket after each full response
- */
- int disable_reuse;
- /*
- * Add more data to log facilities.
- */
- void (JK_METHOD * add_log_items) (jk_ws_service_t *s,
- const char *const *log_names,
- const char *const *log_values,
- unsigned num_of_items);
- /*
- * Iterate through all vhosts
- */
- void *(JK_METHOD * next_vhost) (void *d);
- /*
- * String representation of a vhost
- */
- void (JK_METHOD * vhost_to_text) (void *d, char *buf, size_t len);
- /*
- * Get uw_map associated with a vhost
- */
- jk_uri_worker_map_t *(JK_METHOD * vhost_to_uw_map) (void *d);
- };
- 4.6 共享内存中一些数据结构
- 共享内存中的数据结构基本上都是记录之用。有些参数在运行中会实时变化。
- dist/common/jk_shm.h
- /** jk shm generic worker record structure */
- struct jk_shm_worker_header
- {
- int id;
- int type;
- /* worker name */
- char name[JK_SHM_STR_SIZ+1];
- /* Sequence counter starting at 0 and increasing
- * every time we change the config
- */
- volatile unsigned int sequence;
- };
- typedef struct jk_shm_worker_header jk_shm_worker_header_t;
- /** jk shm ajp13/ajp14 worker record structure */
- struct jk_shm_ajp_worker
- {
- jk_shm_worker_header_t h;
- /* Configuration data mirrored from ajp_worker */
- int cache_timeout;
- int connect_timeout;
- int reply_timeout;
- int prepost_timeout;
- unsigned int recovery_opts;
- int retries;
- int retry_interval;
- unsigned int max_packet_size;
- /* current error state (runtime) of the worker */
- volatile int state;
- /* Statistical data */
- /* Number of currently busy channels */
- volatile int busy;
- /* Maximum number of busy channels
- 该参数并非我们的maxbusy,它是该worker自程序运行以来busy的最大值 */
- volatile int max_busy;
- volatile time_t error_time;
- /* Number of bytes read from remote */
- volatile jk_uint64_t readed;
- /* Number of bytes transferred to remote */
- volatile jk_uint64_t transferred;
- /* Number of times the worker was used */
- volatile jk_uint64_t used;
- /* Number of times the worker was used - snapshot during maintenance */
- volatile jk_uint64_t used_snapshot;
- /* Number of non 200 responses */
- volatile jk_uint32_t errors;
- /* Decayed number of reply_timeout errors */
- volatile jk_uint32_t reply_timeouts;
- /* Number of client errors */
- volatile jk_uint32_t client_errors;
- /* Last reset time */
- volatile time_t last_reset;
- volatile time_t last_maintain_time;
- };
- typedef struct jk_shm_ajp_worker jk_shm_ajp_worker_t;
- /** jk shm lb sub worker record structure */
- struct jk_shm_lb_sub_worker
- {
- jk_shm_worker_header_t h;
- /* route */
- char route[JK_SHM_STR_SIZ+1];
- /* worker domain */
- char domain[JK_SHM_STR_SIZ+1];
- /* worker redirect route */
- char redirect[JK_SHM_STR_SIZ+1];
- /* Number of currently busy channels */
- volatile int busy;
- /* worker distance */
- volatile int distance;
- /* current activation state (config) of the worker */
- volatile int activation;
- /* current error state (runtime) of the worker */
- volatile int state;
- /* Current lb factor */
- volatile int lb_factor;
- /* 我们的参数加在这里*/
- volatile int maxbusy;
- /* Current lb reciprocal factor */
- volatile jk_uint64_t lb_mult;
- /* Current lb value */
- volatile jk_uint64_t lb_value;
- /* Statistical data */
- volatile time_t error_time;
- /* Number of times the worker was elected - snapshot during maintenance */
- volatile jk_uint64_t elected_snapshot;
- /* Number of non 200 responses */
- volatile jk_uint32_t errors;
- };
- typedef struct jk_shm_lb_sub_worker jk_shm_lb_sub_worker_t;
- /** jk shm lb worker record structure */
- struct jk_shm_lb_worker
- {
- jk_shm_worker_header_t h;
- /* Number of currently busy channels,该值是其名下ajp_worker的busy值之和*/
- volatile int busy;
- /* Maximum number of busy channels,该值是其名下ajp_worker的max_busy值之和
- */
- volatile int max_busy;
- int sticky_session;
- int sticky_session_force;
- int recover_wait_time;
- int max_reply_timeouts;
- int retries;
- int retry_interval;
- int lbmethod;
- int lblock;
- unsigned int max_packet_size;
- /* Last reset time */
- volatile time_t last_reset;
- volatile time_t last_maintain_time;
- /* Session cookie */
- char session_cookie[JK_SHM_STR_SIZ+1];
- /* Session path */
- char session_path[JK_SHM_STR_SIZ+1];
- };
- typedef struct jk_shm_lb_worker jk_shm_lb_worker_t;