Mercurial > hg > nginx-site
comparison xml/en/docs/dev/development_guide.xml @ 2410:392e11db3260
Development guide: added the "Common Pitfalls" section.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 23 Jul 2019 19:07:55 +0300 |
parents | e79e32d19ae4 |
children | bd026d5898b8 |
comparison
equal
deleted
inserted
replaced
2409:3bc28d88f34e | 2410:392e11db3260 |
---|---|
7 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> | 7 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> |
8 | 8 |
9 <article name="Development guide" | 9 <article name="Development guide" |
10 link="/en/docs/dev/development_guide.html" | 10 link="/en/docs/dev/development_guide.html" |
11 lang="en" | 11 lang="en" |
12 rev="7"> | 12 rev="8"> |
13 | 13 |
14 <section name="Introduction" id="introduction"> | 14 <section name="Introduction" id="introduction"> |
15 | 15 |
16 | 16 |
17 <section name="Code layout" id="code_layout"> | 17 <section name="Code layout" id="code_layout"> |
256 | 256 |
257 | 257 |
258 <section name="Strings" id="strings"> | 258 <section name="Strings" id="strings"> |
259 | 259 |
260 | 260 |
261 <section name="Overview" id="overview"> | 261 <section name="Overview" id="string_overview"> |
262 | 262 |
263 <para> | 263 <para> |
264 For C strings, nginx uses the unsigned character type pointer | 264 For C strings, nginx uses the unsigned character type pointer |
265 <literal>u_char *</literal>. | 265 <literal>u_char *</literal>. |
266 </para> | 266 </para> |
7262 freeaddrinfo(res); | 7262 freeaddrinfo(res); |
7263 return NGX_ERROR; | 7263 return NGX_ERROR; |
7264 </programlisting> | 7264 </programlisting> |
7265 </para> | 7265 </para> |
7266 </section> | 7266 </section> |
7267 </section> | |
7268 | |
7269 <section name="Common Pitfalls" id="common_pitfals"> | |
7270 | |
7271 <section name="Writing a C module" id="module_pitfall"> | |
7272 | |
7273 <para> | |
7274 The most common pitfall is an attempt to write a full-fledged C module. | |
7275 In most cases your task can be accomplished by creating a proper configuration. | |
7276 If writing a module is inevitable, try to make it | |
7277 as small and simple as possible. | |
7278 For example, a module can only export some | |
7279 <link id="http_variables">variables</link>. | |
7280 </para> | |
7281 | |
7282 <para> | |
7283 Before starting a module, consider the following questions: | |
7284 | |
7285 <list type="bullet"> | |
7286 | |
7287 <listitem> | |
7288 Is it possible to implement a desired feature using already | |
7289 <link doc="../../docs/index.xml">available modules</link>? | |
7290 </listitem> | |
7291 | |
7292 <listitem> | |
7293 Is it possible to solve an issue using built-in scripting languages, | |
7294 such as <link doc="../http/ngx_http_perl_module.xml">Perl</link> | |
7295 or <link doc="../njs/index.xml">njs</link>? | |
7296 </listitem> | |
7297 | |
7298 </list> | |
7299 | |
7300 </para> | |
7301 | |
7302 </section> | |
7303 | |
7304 <section name="C Strings" id="c_strings"> | |
7305 | |
7306 <para> | |
7307 The most used string type in nginx, | |
7308 <link id="string_overview">ngx_str_t</link> is not a C-Style | |
7309 zero-terminated string. | |
7310 You cannot pass the data to standard C library functions | |
7311 such as <c-func>strlen</c-func> or <c-func>strstr</c-func>. | |
7312 Instead, nginx <link id="string_overview">counterparts</link> | |
7313 should be used that accept either <literal>ngx_str_t</literal> | |
7314 or pointer to data and a length. | |
7315 However, there is a case when <literal>ngx_str_t</literal> holds | |
7316 a pointer to a zero-terminated string: strings that come as a result of | |
7317 configuration file parsing are zero-terminated. | |
7318 </para> | |
7319 | |
7320 </section> | |
7321 | |
7322 <section name="Global Variables" id="global_variables"> | |
7323 | |
7324 <para> | |
7325 Avoid using global variables in your modules. | |
7326 Most likely this is an error to have a global variable. | |
7327 Any global data should be tied to a <link id="cycle">configuration cycle</link> | |
7328 and be allocated from the corresponding <link id="pool">memory pool</link>. | |
7329 This allows nginx to perform graceful configuration reloads. | |
7330 An attempt to use global variables will likely break this feature, | |
7331 because it will be impossible to have two configurations at | |
7332 the same time and abandon of them. | |
7333 Sometimes global variables are required. | |
7334 In this case, special attention is needed to manage reconfiguration | |
7335 properly. | |
7336 Also, check if libraries used by your code have implicit | |
7337 global state that may be broken on reload. | |
7338 </para> | |
7339 | |
7340 </section> | |
7341 | |
7342 <section name="Manual Memory Management" id="manual_memory_management"> | |
7343 | |
7344 <para> | |
7345 Instead of dealing with malloc/free approach which is error prone, | |
7346 learn how to use nginx <link id="pool">pools</link>. | |
7347 A pool is created and tied to some object - | |
7348 <link id="http_conf">configuration</link>, | |
7349 <link id="cycle">cycle</link>, | |
7350 <link id="connection">connection</link>, | |
7351 or <link id="http_request">HTTP request</link>. | |
7352 When an object is destroyed, the associated pool is destroyed too. | |
7353 So when working with an object, it is possible to allocate as much as | |
7354 needed from the corresponding pool and don't care about freeing memory, | |
7355 even in case of errors. | |
7356 </para> | |
7357 | |
7358 </section> | |
7359 | |
7360 <section name="Threads" id="threads_pitfalls"> | |
7361 | |
7362 <para> | |
7363 It is recommended to avoid using threads in nginx because it will | |
7364 definitely break things: most nginx functions are not thread-safe. | |
7365 It is expected that a thread will be executing only system calls and | |
7366 thread-safe library functions. | |
7367 If you need to run some code that is not related to client request processing, | |
7368 the proper way is to schedule a timer in the <literal>init_process</literal> | |
7369 module handler and perform required actions in timer handler. | |
7370 Internally nginx makes use of <link id="threads">threads</link> to | |
7371 boost IO-related operations, but this is a special case with a lot | |
7372 of limitations. | |
7373 </para> | |
7374 | |
7375 </section> | |
7376 | |
7377 <section name="Blocking Libraries" id="libraries"> | |
7378 | |
7379 <para> | |
7380 A common mistake is to use libraries that are blocking internally. | |
7381 Most libraries out there are synchronous and blocking by nature. | |
7382 In other words, they perform one operation at a time and waste | |
7383 time waiting response from other peer. | |
7384 As a result, when a request is processed with such library, whole | |
7385 nginx worker is blocked, thus destroying performance. | |
7386 Use only libraries that provide asynchronous interface and don't | |
7387 block whole process. | |
7388 </para> | |
7389 | |
7390 </section> | |
7391 | |
7392 | |
7393 <section name="HTTP Requests to External Services" id="http_requests_to_ext"> | |
7394 | |
7395 <para> | |
7396 Often modules need to perform an HTTP call to some external service. | |
7397 A common mistake is to use some external library, such as libcurl, | |
7398 to perform HTTP request. | |
7399 It is absolutely unnecessary to bring a huge amount of external | |
7400 (probably <link id="using_libraries">blocking</link>!) code | |
7401 for the task which can be accomplished by nginx itself. | |
7402 </para> | |
7403 | |
7404 <para> | |
7405 There are two basic usage scenarios when an external request is needed: | |
7406 | |
7407 <list type="bullet"> | |
7408 | |
7409 <listitem> | |
7410 in the context of processing a client request (for example, in content handler) | |
7411 </listitem> | |
7412 | |
7413 <listitem> | |
7414 in the context of a worker process (for example, timer handler) | |
7415 </listitem> | |
7416 | |
7417 </list> | |
7418 | |
7419 </para> | |
7420 | |
7421 <para> | |
7422 In the first case, the best is to use | |
7423 <link id="http_subrequests">subrequests API</link>. | |
7424 Instead of directly accessing external service, you declare a location | |
7425 in nginx configuration and direct your subrequest to this location. | |
7426 This location is not limited to | |
7427 <link doc="../http/ngx_http_proxy_module.xml" id="proxy_pass">proxying</link> | |
7428 requests, but may contain other nginx directives. | |
7429 An example of such approach is the | |
7430 <link doc="../http/ngx_http_auth_request_module.xml" id="auth_request"/> | |
7431 directive implemented in | |
7432 <link url="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_auth_request_module.c">ngx_http_auth_request module</link>. | |
7433 </para> | |
7434 | |
7435 <para> | |
7436 For the second case, it is possible to use basic HTTP client functionality | |
7437 available in nginx. | |
7438 For example, | |
7439 <link url="http://hg.nginx.org/nginx/file/tip/src/event/ngx_event_openssl_stapling.c">OCSP module</link> | |
7440 implements simple HTTP client. | |
7441 </para> | |
7442 | |
7443 </section> | |
7267 | 7444 |
7268 </section> | 7445 </section> |
7269 | 7446 |
7270 </article> | 7447 </article> |