天天看點

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 isto 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.5jk_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 。

1.    dist/common/jk_lb_worker.h  

2.    struct lb_worker  

3.    {  

4.    /* jk子產品通用worker結構體。包含一些回調函數,不同的worker有不同的函數實作  */  

5.    jk_worker_t worker;  

6.    /* Shared memory worker data */  

7.    jk_shm_lb_worker_t *s;  

8.    char name[JK_SHM_STR_SIZ+1];  

9.    /* Sequence counter starting at 0 and increasing  every time we change the config */  

10.  volatile unsigned int sequence;  

11.  jk_pool_t p;  

12.  jk_pool_atom_t buf[TINY_POOL_SIZE];  

13.  JK_CRIT_SEC cs;  

14.  /*其名下的workers*/  

15.  lb_sub_worker_t *lb_workers;  

16.  unsigned int num_of_workers;  

17.  int sticky_session;  

18.  int sticky_session_force;  

19.  int recover_wait_time;  

20.  int max_reply_timeouts;  

21.  int retries;  

22.  int retry_interval;  

23.  int lbmethod;  

24.  int lblock;  

25.  int maintain_time;  

26.  unsigned int max_packet_size;  

27.  unsigned int next_offset;  

28.  /* Session cookie */  

29.  char session_cookie[JK_SHM_STR_SIZ+1];  

30.  /* Session path */  

31.  char session_path[JK_SHM_STR_SIZ+1];  

32.  };  

33.  lb_sub_worker是由lb_worker支配的ajp_worker。當然lb_sub_worker有不同的類型。  

34.  它們的實際類型存儲在ajp_worker中。  

35.   

36.  dist/common/jk_lb_worker.h  

37.  struct lb_sub_worker  

38.  {  

39.  /* 包含ajp_worker的回調函數及其ajp_worker結構體*/  

40.  jk_worker_t *worker;  

41.  /* Shared memory worker data */  

42.  jk_shm_lb_sub_worker_t *s;  

43.  char name[JK_SHM_STR_SIZ+1];  

44.  /* Sequence counter starting at 0 and increasing  

45.  * every time we change the config  

46.  */  

47.  volatile unsigned int sequence;  

48.  /* route */  

49.  char route[JK_SHM_STR_SIZ+1];  

50.  /* worker domain */  

51.  char domain[JK_SHM_STR_SIZ+1];  

52.  /* worker redirect route */  

53.  char redirect[JK_SHM_STR_SIZ+1];  

54.  /* worker distance */  

55.  int distance;  

56.  /* current activation state (config) of the worker */  

57.  int activation;  

58.  /* Current lb factor */  

59.  int lb_factor;  

60.  /* Current worker index */  

61.  int i;  

62.  /* Current lb reciprocal factor */  

63.  jk_uint64_t lb_mult;  

64.  };  

65.  typedef struct lb_sub_worker lb_sub_worker_t;  

1.    4.2 ajp_worker  

2.    ajp_worker是具體工作的worker,對應後端一個tomcat應用服務。  

3.    dist/common/jk_ajp_common.c  

4.    struct ajp_worker  

5.    {  

6.    /* 包含ajp_worker的回調函數*/  

7.    jk_worker_t worker;  

8.    /* Shared memory worker data */  

9.    jk_shm_ajp_worker_t *s;  

10.  char name[JK_SHM_STR_SIZ+1];  

11.  /* Sequence counter starting at 0 and increasing  

12.  * every time we change the config  

13.  */  

14.  volatile unsigned int sequence;  

15.  jk_pool_t p;  

16.  jk_pool_atom_t buf[TINY_POOL_SIZE];  

17.  JK_CRIT_SEC cs;  

18.  struct sockaddr_in worker_inet_addr; /* Contains host and port */  

19.  unsigned connect_retry_attempts;  

20.  const char *host;  

21.  int port;  

22.  int maintain_time;  

23.  /*  

24.  * Open connections cache...  

25.  *  

26.  * 1. Critical section object to protect the cache.  

27.  * 2. Cache size.  

28.  * 3. An array of "open" endpoints.  

29.  */  

30.  unsigned int ep_cache_sz;  

31.  unsigned int ep_mincache_sz;  

32.  unsigned int ep_maxcache_sz;  

33.  int cache_acquire_timeout;  

34.  ajp_endpoint_t **ep_cache;  

35.  int proto; /* PROTOCOL USED AJP13/AJP14 */  

36.  jk_login_service_t *login;  

37.  /* Weak secret similar with ajp12, used in ajp13 */  

38.  const char *secret;  

39.  /*  

40.  * Post physical connect handler.  

41.  * AJP14 will set here its login handler  

42.  */  

43.  int (*logon) (ajp_endpoint_t * ae, jk_logger_t *l);  

44.  /*  

45.  * Handle Socket Timeouts  

47.  int socket_timeout;  

48.  int socket_connect_timeout;  

49.  int keepalive;  

50.  int socket_buf;  

51.  /*  

52.  * Handle Cache Timeouts  

53.  */  

54.  int cache_timeout;  

55.  /*  

56.  * Handle Connection/Reply Timeouts  

57.  */  

58.  int connect_timeout; /* connect cping/cpong delay in ms (0 means  

59.  disabled) */  

60.  int reply_timeout; /* reply timeout delay in ms (0 means disabled) */  

61.  int prepost_timeout; /* before sending a request cping/cpong timeout  

62.  delay in ms (0 means disabled) */  

63.  int conn_ping_interval; /* interval for sending keepalive cping packets on  

64.  * unused connection */  

65.  int ping_timeout; /* generic cping/cpong timeout. Used for keepalive  

66.  packets or  

67.  * as default for boolean valued connect and  

68.  prepost timeouts.  

69.  */  

70.  unsigned int ping_mode; /* Ping mode flags (which types of cpings should  

71.  be used) */  

72.  /*  

73.  * Recovery options  

74.  */  

75.  unsigned int recovery_opts;  

76.  /*  

77.  * Public property to enable the number of retry attempts  

78.  * on this worker.  

79.  */  

80.  int retries;  

81.  unsigned int max_packet_size; /* Maximum AJP Packet size */  

82.  int retry_interval; /* Number of milliseconds to sleep before  

83.  doing a retry */  

84.  /*  

85.  * HTTP status that will cause failover (0 means disabled)  

86.  */  

87.  unsigned int http_status_fail_num;  

88.  int http_status_fail[JK_MAX_HTTP_STATUS_FAILS];  

89.  };  

90.  4.3 status_worker  

91.  status_worker用于産生一些狀态的統計資訊。  

92.  dist/common/jk_statuc.c  

93.  struct status_worker  

94.  {  

95.  jk_pool_t p;  

96.  jk_pool_atom_t buf[TINY_POOL_SIZE];  

97.  const char *name;  

98.  const char *css;  

99.  const char *ns;  

100.const char *xmlns;  

101.const char *doctype;  

102.const char *prefix;  

103.int read_only;  

104.char **user_names;  

105.unsigned int num_of_users;  

106.int user_case_insensitive;  

107.jk_uint32_t good_mask;  

108.jk_uint32_t bad_mask;  

109.jk_worker_t worker;  

110.jk_worker_env_t *we;  

111.};  

112.4.4 jk_worker和 jk_endpoint  

113.jk_worker是所有worker通用結構體名稱, 主要包含的是一些函數指針。它是一個類  

114.似java中抽象類的概念,各成員函數在從factory函數生産時初始化。  

115.dist/common/jk_service.h  

116.struct jk_worker  

117.{  

118./*  

119.* A 'this' pointer which is used by the subclasses of this class to  

120.* point to data/functions which are specific to a given protocol  

121.* (e.g. ajp12 or ajp13 or ajp14).  

122.*/  

123.void *worker_private;/* 指向ajp_worker,lb_worker結構體 ...*/  

124.int type;  

125./*  

126.* For all of the below (except destroy), the first argument is  

127.* essentially a 'this' pointer.  

128.*/  

129./* 先于init函數調用,用于配置設定各類worker結構體的記憶體,作必要的初始化  

130.* Given a worker which is in the process of being created, and a list  

131.* of configuration options (or 'properties'), check to see if it the  

132.* options are. This will always be called before the init() method.  

133.* The init/validate distinction is a bit hazy to me.  

134.* See jk_ajp13_worker.c/jk_ajp14_worker.c and jk_worker.c-  

135.>wc_create_worker()  

136.*/  

137.int (JK_METHOD * validate) (jk_worker_t *w,  

138.jk_map_t *props,  

139.jk_worker_env_t *we, jk_logger_t *l);  

140./*  

141.* Update worker either from jk_status or reloading from workers.properties  

142.*/  

143.int (JK_METHOD * update) (jk_worker_t *w,  

144.jk_map_t *props,  

145.jk_worker_env_t *we, jk_logger_t *l);  

146./*  

147.* Do whatever initialization needs to be done to start this worker up.  

148.* Configuration options are passed in via the props parameter.  

149.*/  

150.int (JK_METHOD * init) (jk_worker_t *w,  

151.jk_map_t *props,  

152.jk_worker_env_t *we, jk_logger_t *l);  

153./*  

154.* Obtain an endpoint to service a particular request. A pointer to  

155.* the endpoint is stored in pend.  

156.*/  

157.int (JK_METHOD * get_endpoint) (jk_worker_t *w,  

158.jk_endpoint_t **pend, jk_logger_t *l);  

159./*  

160.* Shutdown this worker. The first argument is not a 'this' pointer,  

161.* but rather a pointer to 'this', so that the object can be free'd (I  

162.* think -- though that doesn't seem to be happening. Hmmm).  

163.*/  

164.int (JK_METHOD * destroy) (jk_worker_t **w, jk_logger_t *l);  

165./*  

166.* Maintain this worker.  

167.*/  

168.int (JK_METHOD * maintain) (jk_worker_t *w, time_t now, jk_logger_t *l);  

169.};  

170./* jk_endpoint可以稱之為通用終端服務結構體,各類worker可能有自己的endpoint結構  

171.體。比如ajp_worker, 該終端是用來做具體工作的,比如送出請求,接收AJP資料等等。如  

172.果是lb_worker,該終端是的作用是找出合适ajp_worker, 把任務交給它。* /  

173.struct jk_endpoint  

174.{  

175.jk_uint64_t rd;  

176.jk_uint64_t wr;  

177./*  

178.* Flag to pass back recoverability status from  

179.* a load balancer member to the load balancer itself.  

180.* Depending on the configuration and request status  

181.* recovery is not allowed.  

182.*/  

183.int recoverable;  

184./*  

185.* A 'this' pointer which is used by the subclasses of this class to  

186.* point to data/functions which are specific to a given protocol  

187.* (e.g. ajp12 or ajp13 or ajp14).  

188.*/  

189.void *endpoint_private;  

190./* 該函數是具體的服務函數  

191.* Forward a request to the servlet engine. The request is described  

192.* by the jk_ws_service_t object.  

193.* is_error is either 0 meaning recoverable or set to  

194.* the HTTP error code.  

195.*/  

196.int (JK_METHOD * service) (jk_endpoint_t *e,  

197.jk_ws_service_t *s,  

198.jk_logger_t *l, int *is_error);  

199./*  

200.* Called when this particular endpoint has finished processing a  

201.* request. For some protocols (e.g. ajp12), this frees the memory  

202.* associated with the endpoint. For others (e.g. ajp13/ajp14), this can  

203.* return the endpoint to a cache of already opened endpoints.  

204.*  

205.* Note that the first argument is *not* a 'this' pointer, but is  

206.* rather a pointer to a 'this' pointer. This is necessary, because  

207.* we may need to free this object.  

208.*/  

209.int (JK_METHOD * done) (jk_endpoint_t **p, jk_logger_t *l);  

210.};  

211.4.5 jk_ws_service  

212.該結構體是與apache相關的一些參數或函數,面向HTTP協定,與AJP協定不太相關。  

213.dist/common/jk_service.h  

214.struct jk_ws_service  

215.{  

216./*  

217.* A 'this' pointer which is used by the subclasses of this class to  

218.* point to data which is specific to a given web server platform  

219.* (e.g. Apache or IIS).  

220.*/  

221.void *ws_private;  

222./*  

223.* Provides memory management. All data specific to this request is  

224.* allocated within this pool, which can then be reclaimed at the end  

225.* of the request handling cycle.  

226.*  

227.* Alive as long as the request is alive.  

228.*/  

229.jk_pool_t *pool;  

230./*  

231.* CGI Environment needed by servlets  

232.*/  

233.const char *method;  

234.const char *protocol;  

235.char *req_uri;  

236.const char *remote_addr;  

237.const char *remote_host;  

238.const char *remote_user;  

239.const char *auth_type;  

240.const char *query_string;  

241.const char *server_name;  

242.unsigned server_port;  

243.char *server_software;  

244.jk_uint64_t content_length; /* 64 bit integer that represents the content */  

245./* length should be 0 if unknown. */  

246.unsigned is_chunked; /* 1 if content length is unknown (chunked rq) */  

247.unsigned no_more_chunks; /* 1 if last chunk has been read */  

248.jk_uint64_t content_read; /* number of bytes read */  

249./*  

250.* SSL information  

251.*  

252.* is_ssl - True if request is in ssl connection  

253.* ssl_cert - If available, base64 ASN.1 encoded client certificates.  

254.* ssl_cert_len - Length of ssl_cert, 0 if certificates are not available.  

255.* ssl_cipher - The ssl cipher suite in use.  

256.* ssl_session - The ssl session string  

257.*  

258.* In some servers it is impossible to extract all this information, in this  

259.* case, we are passing NULL.  

260.*/  

261.int is_ssl;  

262.char *ssl_cert;  

263.unsigned ssl_cert_len;  

264.char *ssl_cipher;  

265.char *ssl_session;  

266./*  

267.* SSL extra information for Servlet 2.3 API  

268.*  

269.* ssl_key_size - ssl key size in use  

270.*/  

271.int ssl_key_size;  

272./*  

273.* Headers, names and values.  

274.*/  

275.char **headers_names; /* Names of the request headers */  

276.char **headers_values; /* Values of the request headers */  

277.unsigned num_headers; /* Number of request headers */  

278./*  

279.* Request attributes.  

280.*  

281.* These attributes that were extracted from the web server and are  

282.* sent to Tomcat.  

283.*  

284.* The developer should be able to read them from the ServletRequest  

285.* attributes. Tomcat is required to append org.apache.tomcat. to  

286.* these attribute names.  

287.*/  

288.char **attributes_names; /* Names of the request attributes */  

289.char **attributes_values; /* Values of the request attributes */  

290.unsigned num_attributes; /* Number of request attributes */  

291./*  

292.* The route is in use when the adapter load balance among  

293.* several workers. It is the ID of a specific target in the load balance  

294.* group. We are using this variable to implement target session  

295.* affinity  

296.*/  

297.const char *route;  

298./* Temp solution for auth. For native1 it'll be sent on each request,  

299.if an option is present. For native2 it'll be sent with the first  

300.request. On java side, both cases will work. For tomcat3.2 or  

301.a version that doesn't support secret - don't set the secret,  

302.and it'll work.  

303.*/  

304.const char *secret;  

305./*  

306.* Area to get POST data for fail-over recovery in POST  

307.*/  

308.jk_msg_buf_t *reco_buf;  

309.int reco_status;  

310./*  

311.* If set call flush after each write  

312.*/  

313.int flush_packets;  

314./*  

315.* If set call flush after AJP13_SEND_HEADERS.  

316.*/  

317.int flush_header;  

318./*  

319.* service extensions  

320.*/  

321.svc_extension_t extension;  

322./*  

323.* JK_TRUE if response headers have been sent back  

324.*/  

325.int response_started;  

326./*  

327.* JK_TRUE if response should not be send to the client  

328.*/  

329.int response_blocked;  

330./*  

331.* HTTP status sent from container.  

332.*/  

333.int http_response_status;  

334./* Uri worker map. Added for virtual host support  

335.*/  

336.jk_uri_worker_map_t *uw_map;  

337./* 下面這些回調函數實作都可以在mod_jk.c找到  

338.* Callbacks into the web server. For each, the first argument is  

339.* essentially a 'this' pointer. All return JK_TRUE on success  

340.* and JK_FALSE on failure.  

341.*/  

342./*  

343.* Send the response headers to the browser.  

344.*/  

345.int (JK_METHOD * start_response) (jk_ws_service_t *s,  

346.int status,  

347.const char *reason,  

348.const char *const *header_names,  

349.const char *const *header_values,  

350.unsigned num_of_headers);  

351./*  

352.* Read a chunk of the request body into a buffer. Attempt to read len  

353.* bytes into the buffer. Write the number of bytes actually read into  

354.* actually_read.  

355.*/  

356.int (JK_METHOD * read) (jk_ws_service_t *s,  

357.void *buffer,  

358.unsigned len, unsigned *actually_read);  

359./*  

360.* Write a chunk of response data back to the browser.  

361.*/  

362.int (JK_METHOD * write) (jk_ws_service_t *s,  

363.const void *buffer, unsigned len);  

364./*  

365.* Flush a chunk of response data back to the browser.  

366.*/  

367.void (JK_METHOD * flush) (jk_ws_service_t *s);  

368./*  

369.* Done with sending response back to the browser.  

370.*/  

371.void (JK_METHOD * done) (jk_ws_service_t *s);  

372./*  

373.* If set do not reuse socket after each full response  

374.*/  

375.int disable_reuse;  

376./*  

377.* Add more data to log facilities.  

378.*/  

379.void (JK_METHOD * add_log_items) (jk_ws_service_t *s,  

380.const char *const *log_names,  

381.const char *const *log_values,  

382.unsigned num_of_items);  

383./*  

384.* Iterate through all vhosts  

385.*/  

386.void *(JK_METHOD * next_vhost) (void *d);  

387./*  

388.* String representation of a vhost  

389.*/  

390.void (JK_METHOD * vhost_to_text) (void *d, char *buf, size_t len);  

391./*  

392.* Get uw_map associated with a vhost  

393.*/  

394.jk_uri_worker_map_t *(JK_METHOD * vhost_to_uw_map) (void *d);  

395.};  

1.       

1.    4.6 共享記憶體中一些資料結構  

2.    共享記憶體中的資料結構基本上都是記錄之用。有些參數在運作中會實時變化。  

1.    dist/common/jk_shm.h  

2.    /** jk shm generic worker record structure */  

3.    struct jk_shm_worker_header  

4.    {  

5.    int id;  

6.    int type;  

7.    /* worker name */  

9.    /* Sequence counter starting at 0 and increasing  

10.  * every time we change the config  

11.  */  

12.  volatile unsigned int sequence;  

13.  };  

14.  typedef struct jk_shm_worker_header jk_shm_worker_header_t;  

15.  /** jk shm ajp13/ajp14 worker record structure */  

16.  struct jk_shm_ajp_worker  

17.  {  

18.  jk_shm_worker_header_t h;  

19.  /* Configuration data mirrored from ajp_worker */  

20.  int cache_timeout;  

21.  int connect_timeout;  

22.  int reply_timeout;  

23.  int prepost_timeout;  

24.  unsigned int recovery_opts;  

25.  int retries;  

26.  int retry_interval;  

27.  unsigned int max_packet_size;  

28.  /* current error state (runtime) of the worker */  

29.  volatile int state;  

30.  /* Statistical data */  

31.  /* Number of currently busy channels */  

32.  volatile int busy;  

33.  /* Maximum number of busy channels  

34.  該參數并非我們的maxbusy,它是該worker自程式運作以來busy的最大值 */  

35.  volatile int max_busy;  

36.  volatile time_t error_time;  

37.  /* Number of bytes read from remote */  

38.  volatile jk_uint64_t readed;  

39.  /* Number of bytes transferred to remote */  

40.  volatile jk_uint64_t transferred;  

41.  /* Number of times the worker was used */  

42.  volatile jk_uint64_t used;  

43.  /* Number of times the worker was used - snapshot during maintenance */  

44.  volatile jk_uint64_t used_snapshot;  

45.  /* Number of non 200 responses */  

46.  volatile jk_uint32_t errors;  

47.  /* Decayed number of reply_timeout errors */  

48.  volatile jk_uint32_t reply_timeouts;  

49.  /* Number of client errors */  

50.  volatile jk_uint32_t client_errors;  

51.  /* Last reset time */  

52.  volatile time_t last_reset;  

53.  volatile time_t last_maintain_time;  

54.  };  

55.  typedef struct jk_shm_ajp_worker jk_shm_ajp_worker_t;  

56.  /** jk shm lb sub worker record structure */  

57.  struct jk_shm_lb_sub_worker  

58.  {  

59.  jk_shm_worker_header_t h;  

60.  /* route */  

61.  char route[JK_SHM_STR_SIZ+1];  

62.  /* worker domain */  

63.  char domain[JK_SHM_STR_SIZ+1];  

64.  /* worker redirect route */  

65.  char redirect[JK_SHM_STR_SIZ+1];  

66.  /* Number of currently busy channels */  

67.  volatile int busy;  

68.  /* worker distance */  

69.  volatile int distance;  

70.  /* current activation state (config) of the worker */  

71.  volatile int activation;  

72.  /* current error state (runtime) of the worker */  

73.  volatile int state;  

74.  /* Current lb factor */  

75.  volatile int lb_factor;  

76.  /* 我們的參數加在這裡*/  

77.  volatile int maxbusy;  

78.  /* Current lb reciprocal factor */  

79.  volatile jk_uint64_t lb_mult;  

80.  /* Current lb value */  

81.  volatile jk_uint64_t lb_value;  

82.  /* Statistical data */  

83.  volatile time_t error_time;  

84.  /* Number of times the worker was elected - snapshot during maintenance */  

85.  volatile jk_uint64_t elected_snapshot;  

86.  /* Number of non 200 responses */  

87.  volatile jk_uint32_t errors;  

88.  };  

89.  typedef struct jk_shm_lb_sub_worker jk_shm_lb_sub_worker_t;  

90.  /** jk shm lb worker record structure */  

91.  struct jk_shm_lb_worker  

92.  {  

93.  jk_shm_worker_header_t h;  

94.  /* Number of currently busy channels,該值是其名下ajp_worker的busy值之和*/  

95.  volatile int busy;  

96.  /* Maximum number of busy channels,該值是其名下ajp_worker的max_busy值之和  

97.  */  

98.  volatile int max_busy;  

99.  int sticky_session;  

100.int sticky_session_force;  

101.int recover_wait_time;  

102.int max_reply_timeouts;  

103.int retries;  

104.int retry_interval;  

105.int lbmethod;  

106.int lblock;  

107.unsigned int max_packet_size;  

108./* Last reset time */  

109.volatile time_t last_reset;  

110.volatile time_t last_maintain_time;  

111./* Session cookie */  

112.char session_cookie[JK_SHM_STR_SIZ+1];  

113./* Session path */  

114.char session_path[JK_SHM_STR_SIZ+1];  

115.};  

116.typedef struct jk_shm_lb_worker jk_shm_lb_worker_t;