modul nginx secara amnya dibahagikan kepada tiga kategori: pengendali, penapis dan huluan. Dalam bab-bab sebelum ini, pembaca telah pun mengetahui tentang pengendali dan penapis. Menggunakan kedua-dua jenis modul ini, nginx boleh menyelesaikan mana-mana kerja bersendirian dengan mudah.
Modul huluan akan membolehkan nginx melepasi batasan satu mesin dan melengkapkan penerimaan, pemprosesan dan penghantaran data rangkaian.
Fungsi pemajuan data menyediakan nginx dengan keupayaan pemprosesan mendatar merentas satu mesin, membebaskan nginx daripada pengehadan hanya menyediakan satu fungsi untuk nod terminal, dan membolehkannya mempunyai aplikasi rangkaian- pembongkaran aras Membahagi, membungkus dan menyepadukan fungsi.
Pemajuan data ialah komponen utama keupayaan nginx untuk membina aplikasi rangkaian. Sudah tentu, disebabkan isu kos pembangunan, komponen utama aplikasi rangkaian sering dibangunkan pada mulanya menggunakan bahasa pengaturcaraan peringkat tinggi. Tetapi apabila sistem mencapai skala tertentu dan lebih banyak penekanan diberikan pada prestasi, untuk mencapai matlamat prestasi yang diperlukan, komponen yang dibangunkan dalam bahasa peringkat tinggi mesti diubah suai secara struktur.
Pada masa ini, dari segi kos pengubahsuaian, modul huluan nginx menunjukkan kelebihannya kerana ia sememangnya pantas. Di samping itu, gandingan hierarki dan longgar yang disediakan oleh sistem konfigurasi nginx menjadikan sistem berskala ke tahap yang agak tinggi.
Pada asasnya, hulu kepunyaan pengendali, tetapi ia tidak menjana kandungannya sendiri, tetapi memperoleh kandungannya dengan meminta pelayan hujung belakang, jadi ia dipanggil huluan (hulu) . Keseluruhan proses meminta dan mendapatkan kandungan respons telah dirangkumkan dalam nginx, jadi modul huluan hanya perlu membangunkan beberapa fungsi panggil balik untuk menyelesaikan kerja tertentu seperti membina permintaan dan menghuraikan respons.
Fungsi panggil balik modul huluan disenaraikan seperti berikut:
函数名称 | 描述 |
---|---|
create_request | 生成发送到后端服务器的请求缓冲(缓冲链),在初始化upstream 时使用 |
reinit_request | 在某台后端服务器出错的情况,nginx会尝试另一台后端服务器。 nginx选定新的服务器以后,会先调用此函数,以重新初始化 upstream模块的工作状态,然后再次进行upstream连接 |
process_header | 处理后端服务器返回的信息头部。所谓头部是与upstream server 通信的协议规定的,比如HTTP协议的header部分,或者memcached 协议的响应状态部分 |
abort_request | 在客户端放弃请求时被调用。不需要在函数中实现关闭后端服务 器连接的功能,系统会自动完成关闭连接的步骤,所以一般此函 数不会进行任何具体工作 |
finalize_request | 正常完成与后端服务器的请求后调用该函数,与abort_request 相同,一般也不会进行任何具体工作 |
input_filter | 处理后端服务器返回的响应正文。nginx默认的input_filter会 将收到的内容封装成为缓冲区链ngx_chain。该链由upstream的 out_bufs指针域定位,所以开发人员可以在模块以外通过该指针得到后端服务器返回的正文数据。memcached模块实现了自己的 input_filter,在后面会具体分析这个模块。 |
input_filter_init | 初始化input filter的上下文。nginx默认的input_filter_init 直接返回 |
Memcache ialah sistem cache teragih berprestasi tinggi yang telah digunakan secara meluas. memcache mentakrifkan protokol komunikasi peribadi supaya memcache tidak boleh diakses melalui permintaan HTTP. Walau bagaimanapun, protokol itu sendiri adalah mudah dan cekap, dan memcache digunakan secara meluas, jadi kebanyakan bahasa dan platform pembangunan moden menyediakan sokongan memcache untuk memudahkan pembangun menggunakan memcache.
nginx menyediakan modul ngx_http_memcached, yang menyediakan fungsi membaca data daripada memcache, tetapi tidak menyediakan fungsi menulis data ke memcache.
Modul huluan menggunakan kaedah capaian modul pengendali.
Pada masa yang sama, reka bentuk sistem arahan modul huluan juga mengikut peraturan asas modul pengendali: modul akan dilaksanakan hanya selepas mengkonfigurasi modul.
Jadi, apakah yang istimewa tentang modul huluan? Itulah fungsi pemprosesan modul huluan Operasi yang dilakukan oleh fungsi pemprosesan modul huluan termasuk proses tetap: (ambil modul memcached sebagai contoh, dalam fungsi pemprosesan ngx_http_memcached_handler memcached)
Buat struktur data huluan:
ngx_http_upstream_t *u; if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream;
Tetapkan teg dan skema modul. Skema hanya akan digunakan untuk log sekarang dan teg akan digunakan untuk pengurusan buf_chain:
ngx_str_set(&u->schema, "memcached://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
Tetapkan struktur data senarai pelayan hujung belakang hulu:
mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); u->conf = &mlcf->upstream;
Tetapkan fungsi panggil balik huluan:
u->create_request = ngx_http_memcached_create_request; u->reinit_request = ngx_http_memcached_reinit_request; u->process_header = ngx_http_memcached_process_header; u->abort_request = ngx_http_memcached_abort_request; u->finalize_request = ngx_http_memcached_finalize_request; u->input_filter_init = ngx_http_memcached_filter_init; u->input_filter = ngx_http_memcached_filter;
Buat dan tetapkan struktur data persekitaran huluan:
ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_memcached_module); u->input_filter_ctx = ctx;
Selesaikan kerja permulaan dan penamat huluan:
r->main->count++; ngx_http_upstream_init(r); return NGX_DONE;
Ini benar untuk mana-mana modul huluan, semudah memcached, sekompleks proksi dan fastcgi.
Perbezaan terbesar antara modul huluan yang berbeza dalam 6 langkah ini akan muncul dalam langkah 2, 3, 4 dan 5.
Langkah 2 dan 4 mudah difahami Bendera yang ditetapkan oleh modul berbeza dan fungsi panggil balik yang digunakan pasti berbeza. Langkah 5 juga tidak sukar untuk difahami.
Hanya langkah 3 sedikit mengelirukan modul yang berbeza mempunyai strategi yang sangat berbeza apabila mendapatkan senarai pelayan bahagian belakang Ada yang semudah dan jelas seperti memcached, manakala yang lain adalah sama kompleksnya dengan proksi.
Langkah 6 biasanya konsisten antara modul yang berbeza. Tingkatkan kiraan sebanyak 1 dan kembalikan NGX_DONE.
Apabila nginx menghadapi situasi ini, walaupun ia akan menganggap bahawa pemprosesan permintaan semasa telah ditamatkan, ia tidak akan melepaskan sumber memori yang digunakan oleh permintaan itu, ia juga tidak akan menutup sambungan dengan klien.
Sebab mengapa ini diperlukan adalah kerana nginx telah mewujudkan hubungan satu dengan satu antara permintaan huluan dan permintaan pelanggan Apabila kemudiannya menggunakan ngx_event_pipe untuk menghantar semula respons huluan kepada pelanggan, maklumat pelanggan yang disimpan ini juga akan digunakan. struktur data.
Ikat permintaan huluan dan permintaan pelanggan satu-satu. Reka bentuk ini mempunyai kelebihan dan kekurangan. Kelebihannya ialah ia memudahkan pembangunan modul dan membolehkan anda menumpukan pada logik modul Walau bagaimanapun, kelemahannya adalah sama jelasnya.
Fungsi panggil balik: (Masih mengambil fungsi pemprosesan modul memcached sebagai contoh)
ngx_http_memcached_create_request: Sangat mudah untuk menjana satu mengikut kunci kandungan yang ditetapkan, kemudian jana permintaan "dapatkan $key" dan letakkannya dalam r->upstream->request_bufs.
ngx_http_memcached_reinit_request: Tiada permulaan diperlukan.
ngx_http_memcached_abort_request: Tiada tindakan tambahan diperlukan.
ngx_http_memcached_finalize_request: Tiada tindakan tambahan diperlukan.
ngx_http_memcached_process_header: Fungsi fokus perniagaan modul. Maklumat pengepala protokol memcache ditakrifkan sebagai baris pertama teks dan kodnya adalah seperti berikut:
#define LF (u_char) '\n' for (p = u->buffer.pos; p < u->buffer.last; p++) { if (*p == LF) { goto found; } }
Jika aksara LF (‘n’) tidak ditemui dalam data yang telah dibaca ke dalam penimbal, Fungsi mengembalikan NGX_AGAIN, menunjukkan bahawa pengepala belum dibaca sepenuhnya dan data perlu terus dibaca. nginx akan memanggil fungsi ini sekali lagi selepas menerima data baharu.
nginx hanya akan menggunakan satu cache semasa memproses pengepala respons pelayan bahagian belakang Semua data berada dalam cache ini, jadi apabila menghuraikan maklumat pengepala, tidak perlu mempertimbangkan fakta bahawa maklumat pengepala menjangkau berbilang. tembolok. Jika pengepala terlalu besar dan tidak boleh disimpan dalam cache ini, nginx akan mengembalikan mesej ralat kepada klien dan merekodkan log ralat, menunjukkan bahawa cache tidak cukup besar.
Tanggungjawab penting ngx_http_memcached_process_header adalah untuk menterjemah status yang dikembalikan oleh pelayan bahagian belakang ke dalam status yang dikembalikan kepada klien. Contohnya:
u->headers_in.content_length_n = ngx_atoof(start, p - start); ··· u->headers_in.status_n = 200; u->state->status = 200; ··· u->headers_in.status_n = 404; u->state->status = 404;
u->state digunakan untuk mengira pembolehubah berkaitan huluan. Contohnya, u->state->status akan digunakan untuk mengira nilai pembolehubah "upstream_status". u->headers_in akan dikembalikan sebagai kod status dalam respons kepada klien. Dan u->headers_in.content_length_n menetapkan panjang respons yang dikembalikan kepada klien.
Dalam fungsi ini, anda mesti mengalihkan pos penunjuk baca ke belakang selepas memproses maklumat pengepala, jika tidak, data ini juga akan disalin ke badan respons yang dikembalikan kepada klien, mengakibatkan kandungan badan menjadi tidak konsisten betul.
Fungsi ngx_http_memcached_process_header melengkapkan pemprosesan yang betul bagi pengepala respons dan harus mengembalikan NGX_OK. Jika NGX_AGAIN dikembalikan, ini bermakna data lengkap belum dibaca dan data perlu diteruskan untuk dibaca dari pelayan bahagian belakang. Mengembalikan NGX_DECLINED tidak bermakna Sebarang nilai pulangan lain dianggap sebagai status ralat dan nginx akan menamatkan permintaan huluan dan mengembalikan mesej ralat.
ngx_http_memcached_filter_init: Betulkan panjang kandungan yang diterima daripada pelayan bahagian belakang. Kerana bahagian panjang ini tidak ditambah semasa memproses pengepala.
ngx_http_memcached_filter:
Modul memcached ialah modul yang jarang ditemui dengan fungsi panggil balik untuk memproses teks.
Oleh kerana modul memcached perlu menapis CRLF "END" CRLF pada penghujung teks, ia melaksanakan fungsi panggil balik penapisnya sendiri.
Maksud sebenar pemprosesan teks adalah untuk merangkum kandungan sah teks yang diterima daripada pelayan bahagian belakang ke dalam ngx_chain_t dan menambahkannya pada penghujung u->out_bufs.
nginx tidak menyalin data, tetapi menetapkan struktur data ngx_buf_t untuk menghala ke kawasan memori data ini, dan kemudian mengatur buf ini mengikut ngx_chain_t. Pelaksanaan ini mengelakkan pemindahan memori berskala besar dan merupakan salah satu sebab mengapa nginx cekap.
Atas ialah kandungan terperinci Cara menggunakan modul huluan dalam Nginx. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!