1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
4 <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" />
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 This file is generated from xml source: DO NOT EDIT
8 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 <title>mod_unique_id - Apache HTTP Server Version 2.5</title>
11 <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
12 <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
13 <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" />
14 <script src="../style/scripts/prettify.min.js" type="text/javascript">
17 <link href="../images/favicon.ico" rel="shortcut icon" /></head>
19 <div id="page-header">
20 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
21 <p class="apache">Apache HTTP Server Version 2.5</p>
22 <img alt="" src="../images/feather.png" /></div>
23 <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div>
25 <a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.5</a> > <a href="./">Modules</a></div>
26 <div id="page-content">
27 <div id="preamble"><h1>Apache Module mod_unique_id</h1>
29 <p><span>Available Languages: </span><a href="../en/mod/mod_unique_id.html" title="English"> en </a> |
30 <a href="../fr/mod/mod_unique_id.html" hreflang="fr" rel="alternate" title="Français"> fr </a> |
31 <a href="../ja/mod/mod_unique_id.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> |
32 <a href="../ko/mod/mod_unique_id.html" hreflang="ko" rel="alternate" title="Korean"> ko </a></p>
34 <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Provides an environment variable with a unique
35 identifier for each request</td></tr>
36 <tr><th><a href="module-dict.html#Status">Status:</a></th><td>Extension</td></tr>
37 <tr><th><a href="module-dict.html#ModuleIdentifier">Module Identifier:</a></th><td>unique_id_module</td></tr>
38 <tr><th><a href="module-dict.html#SourceFile">Source File:</a></th><td>mod_unique_id.c</td></tr></table>
42 <p>This module provides a magic token for each request which is
43 guaranteed to be unique across "all" requests under very
44 specific conditions. The unique identifier is even unique
45 across multiple machines in a properly configured cluster of
46 machines. The environment variable <code>UNIQUE_ID</code> is
47 set to the identifier for each request. Unique identifiers are
48 useful for various reasons which are beyond the scope of this
51 <div id="quickview"><h3>Topics</h3>
53 <li><img alt="" src="../images/down.gif" /> <a href="#theory">Theory</a></li>
54 </ul><h3 class="directives">Directives</h3>
55 <p>This module provides no
57 <h3>Bugfix checklist:</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">HTTPD changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&list_id=144532&product=Apache%20httpd-2&query_format=specific&order=changeddate%20DESC%2Cpriority%2Cbug_severity&component=mod_unique_id">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></li></ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
58 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
60 <h2><a name="theory" id="theory">Theory</a></h2>
63 <p>First a brief recap of how the Apache server works on Unix
64 machines. This feature currently isn't supported on Windows NT.
65 On Unix machines, Apache creates several children, the children
66 process requests one at a time. Each child can serve multiple
67 requests in its lifetime. For the purpose of this discussion,
68 the children don't share any data with each other. We'll refer
69 to the children as <dfn>httpd processes</dfn>.</p>
71 <p>Your website has one or more machines under your
72 administrative control, together we'll call them a cluster of
73 machines. Each machine can possibly run multiple instances of
74 Apache. All of these collectively are considered "the
75 universe", and with certain assumptions we'll show that in this
76 universe we can generate unique identifiers for each request,
77 without extensive communication between machines in the
80 <p>The machines in your cluster should satisfy these
81 requirements. (Even if you have only one machine you should
82 synchronize its clock with NTP.)</p>
85 <li>The machines' times are synchronized via NTP or other
86 network time protocol.</li>
88 <li>The machines' hostnames all differ, such that the module
89 can do a hostname lookup on the hostname and receive a
90 different IP address for each machine in the cluster.</li>
93 <p>As far as operating system assumptions go, we assume that
94 pids (process ids) fit in 32-bits. If the operating system uses
95 more than 32-bits for a pid, the fix is trivial but must be
96 performed in the code.</p>
98 <p>Given those assumptions, at a single point in time we can
99 identify any httpd process on any machine in the cluster from
100 all other httpd processes. The machine's IP address and the pid
101 of the httpd process are sufficient to do this. A httpd process
102 can handle multiple requests simultaneously if you use a
103 multi-threaded MPM. In order to identify threads, we use a thread
104 index Apache httpd uses internally. So in order to
105 generate unique identifiers for requests we need only
106 distinguish between different points in time.</p>
108 <p>To distinguish time we will use a Unix timestamp (seconds
109 since January 1, 1970 UTC), and a 16-bit counter. The timestamp
110 has only one second granularity, so the counter is used to
111 represent up to 65536 values during a single second. The
112 quadruple <em>( ip_addr, pid, time_stamp, counter )</em> is
113 sufficient to enumerate 65536 requests per second per httpd
114 process. There are issues however with pid reuse over time, and
115 the counter is used to alleviate this issue.</p>
117 <p>When an httpd child is created, the counter is initialized
118 with ( current microseconds divided by 10 ) modulo 65536 (this
119 formula was chosen to eliminate some variance problems with the
120 low order bits of the microsecond timers on some systems). When
121 a unique identifier is generated, the time stamp used is the
122 time the request arrived at the web server. The counter is
123 incremented every time an identifier is generated (and allowed
126 <p>The kernel generates a pid for each process as it forks the
127 process, and pids are allowed to roll over (they're 16-bits on
128 many Unixes, but newer systems have expanded to 32-bits). So
129 over time the same pid will be reused. However unless it is
130 reused within the same second, it does not destroy the
131 uniqueness of our quadruple. That is, we assume the system does
132 not spawn 65536 processes in a one second interval (it may even
133 be 32768 processes on some Unixes, but even this isn't likely
136 <p>Suppose that time repeats itself for some reason. That is,
137 suppose that the system's clock is screwed up and it revisits a
138 past time (or it is too far forward, is reset correctly, and
139 then revisits the future time). In this case we can easily show
140 that we can get pid and time stamp reuse. The choice of
141 initializer for the counter is intended to help defeat this.
142 Note that we really want a random number to initialize the
143 counter, but there aren't any readily available numbers on most
144 systems (<em>i.e.</em>, you can't use rand() because you need
145 to seed the generator, and can't seed it with the time because
146 time, at least at one second resolution, has repeated itself).
147 This is not a perfect defense.</p>
149 <p>How good a defense is it? Suppose that one of your machines
150 serves at most 500 requests per second (which is a very
151 reasonable upper bound at this writing, because systems
152 generally do more than just shovel out static files). To do
153 that it will require a number of children which depends on how
154 many concurrent clients you have. But we'll be pessimistic and
155 suppose that a single child is able to serve 500 requests per
156 second. There are 1000 possible starting counter values such
157 that two sequences of 500 requests overlap. So there is a 1.5%
158 chance that if time (at one second resolution) repeats itself
159 this child will repeat a counter value, and uniqueness will be
160 broken. This was a very pessimistic example, and with real
161 world values it's even less likely to occur. If your system is
162 such that it's still likely to occur, then perhaps you should
163 make the counter 32 bits (by editing the code).</p>
165 <p>You may be concerned about the clock being "set back" during
166 summer daylight savings. However this isn't an issue because
167 the times used here are UTC, which "always" go forward. Note
168 that x86 based Unixes may need proper configuration for this to
169 be true -- they should be configured to assume that the
170 motherboard clock is on UTC and compensate appropriately. But
171 even still, if you're running NTP then your UTC time will be
172 correct very shortly after reboot.</p>
175 <p>The <code>UNIQUE_ID</code> environment variable is
176 constructed by encoding the 144-bit (32-bit IP address, 32 bit
177 pid, 32 bit time stamp, 16 bit counter, 32 bit thread index)
179 alphabet <code>[A-Za-z0-9@-]</code> in a manner similar to MIME
180 base64 encoding, producing 24 characters. The MIME base64
181 alphabet is actually <code>[A-Za-z0-9+/]</code> however
182 <code>+</code> and <code>/</code> need to be specially encoded
183 in URLs, which makes them less desirable. All values are
184 encoded in network byte ordering so that the encoding is
185 comparable across architectures of different byte ordering. The
186 actual ordering of the encoding is: time stamp, IP address,
187 pid, counter. This ordering has a purpose, but it should be
188 emphasized that applications should not dissect the encoding.
189 Applications should treat the entire encoded
190 <code>UNIQUE_ID</code> as an opaque token, which can be
191 compared against other <code>UNIQUE_ID</code>s for equality
194 <p>The ordering was chosen such that it's possible to change
195 the encoding in the future without worrying about collision
196 with an existing database of <code>UNIQUE_ID</code>s. The new
197 encodings should also keep the time stamp as the first element,
198 and can otherwise use the same alphabet and bit length. Since
199 the time stamps are essentially an increasing sequence, it's
200 sufficient to have a <em>flag second</em> in which all machines
201 in the cluster stop serving any request, and stop using the old
202 encoding format. Afterwards they can resume requests and begin
203 issuing the new encodings.</p>
205 <p>This we believe is a relatively portable solution to this
206 problem. The identifiers
207 generated have essentially an infinite life-time because future
208 identifiers can be made longer as required. Essentially no
209 communication is required between machines in the cluster (only
210 NTP synchronization is required, which is low overhead), and no
211 communication between httpd processes is required (the
212 communication is implicit in the pid value assigned by the
213 kernel). In very specific situations the identifier can be
214 shortened, but more information needs to be assumed (for
215 example the 32-bit IP address is overkill for any site, but
216 there is no portable shorter replacement for it). </p>
219 <div class="bottomlang">
220 <p><span>Available Languages: </span><a href="../en/mod/mod_unique_id.html" title="English"> en </a> |
221 <a href="../fr/mod/mod_unique_id.html" hreflang="fr" rel="alternate" title="Français"> fr </a> |
222 <a href="../ja/mod/mod_unique_id.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> |
223 <a href="../ko/mod/mod_unique_id.html" hreflang="ko" rel="alternate" title="Korean"> ko </a></p>
224 </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
225 <script type="text/javascript"><!--//--><![CDATA[//><!--
226 var comments_shortname = 'httpd';
227 var comments_identifier = 'http://httpd.apache.org/docs/trunk/mod/mod_unique_id.html';
229 if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
230 d.write('<div id="comments_thread"><\/div>');
231 var s = d.createElement('script');
232 s.type = 'text/javascript';
234 s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
235 (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
238 d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
240 })(window, document);
241 //--><!]]></script></div><div id="footer">
242 <p class="apache">Copyright 2016 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
243 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
244 if (typeof(prettyPrint) !== 'undefined') {