Ισχυροί τρόποι για την υπερφόρτιση του διακομιστή NGINX και τη βελτίωση της απόδοσής του

Το NGINX είναι ίσως ο πιο ευέλικτος διακομιστής ιστού εκεί έξω και μπορεί να νικήσει άλλους διακομιστές όταν ρυθμιστεί σωστά. Μπορεί επίσης να κάνει άλλα σημαντικά πράγματα, όπως εξισορρόπηση φορτίου, προσωρινή αποθήκευση HTTP και μπορεί να χρησιμοποιηθεί ως αντίστροφος διακομιστής μεσολάβησης.

Με τα χρόνια, έχουμε δει τόσες πολλές διαμορφώσεις που βελτιώνουν την ασφάλεια και αυξάνουν την απόδοση της εφαρμογής ιστού σας συνολικά - επιτρέποντάς σας να παρακολουθείτε τις τελευταίες τάσεις.

Θα μοιραστώ την μινιμαλιστική διαμόρφωση NGINX που βρήκα ότι είναι η πιο βελτιστοποιημένη που έχω χρησιμοποιήσει για το νέο νέο εργαλείο VisaList Έπρεπε να κάνω πολλή αναζήτηση και έρευνα για τη βελτίωση της απόδοσης του τελευταίου μίλι στον ιστότοπό μου και σκέφτηκα ότι η διαδικασία μπορεί να βοηθήσει τουλάχιστον μερικούς άλλους - γι 'αυτό το μοιράζομαι εδώ.

Γιατί;

Με αυτές τις αλλαγές, κατάφερα να βρω το παρακάτω αποτέλεσμα για τη νέα μου εφαρμογή ιστού:

Βαθμολογία ταχύτητας σελίδας : Πληροφορίες ταχύτητας σελίδας

Βαθμολογία Lighthouse: Chrome Dev Tools Lighthouse

Βαθμολογία διακομιστή: Δοκιμή Qualys SSL Server

Μπορείτε επίσης να αποκτήσετε εύκολα αυτά τα οφέλη απόδοσης. Μπορείτε δεν χρειάζεται να είναι μια DevOps ειδικός για να κάνει αυτές τις βελτιστοποιήσεις. Έτσι οποιοσδήποτε είναι νέος σε εφαρμογές Ιστού και χρησιμοποιεί NGINX θα το βρει πολύ χρήσιμο.

Εάν είστε ειδικός, τότε θα μπορούσατε να αφήσετε τις απόψεις σας στα σχόλια, ώστε οι νέοι προγραμματιστές σαν κι εμένα να μπορούν να μάθουν και να δημιουργήσουν μια ισχυρή και θετική κοινότητα Ιστού γύρω μας. ✨ Go Web Developers!

Αυτό το άρθρο προϋποθέτει ότι διαθέτετε διακομιστή Ubuntu 16.04 (Xenial) και διακομιστή WebApp Vue.js (ή οποιοδήποτε άλλο πλαίσιο JS) εφαρμογή έτοιμη για προβολή μέσω NGINX μαζί με το διακομιστή API. Εάν δεν έχετε εγκαταστήσει το NGINX και χρειάζεστε βοήθεια για να το κάνετε αυτό, μπορείτε να δείτε αυτό το άρθρο .

Λοιπόν, ποιες είναι αυτές οι βελτιστοποιήσεις για τις οποίες μιλώ; Ας δούμε τον κωδικό!

Βελτιστοποιήσεις

Τα καλά νέα είναι ότι πρέπει να ασχοληθείτε μόνο με δύο αρχεία. Το ένα είναι η συνολική σας διαμόρφωση NGINX, η οποία ισχύει για όλες τις εφαρμογές ιστού (μπορείτε να έχετε πολλές εφαρμογές ιστού όπως ιστότοπο, API, στατικό διακομιστή και ούτω καθεξής). Το άλλο είναι συγκεκριμένο για τον τομέα σας, το οποίο, ας πούμε, είναι example.com. Αντικαταστήστε example.comμε τον δικό σας τομέα. Εδώ χρησιμοποιώ μόνο το γυμνό τομέα χωρίς www. Θα το καλύψω σύντομα.

Ανοίξτε τα αρχεία διαμόρφωσης NGINX ή συγκεκριμένα για τον τομέα σας χρησιμοποιώντας αυτές τις εντολές:

sudo nano /etc/nginx/nginx.conf sudo nano /etc/nginx/sites-available/example.com

Συμπίεση περιεχομένου

Είναι το Brotli καλύτερο από το GZip ; Ναι και Όχι. Όταν το πρόγραμμα περιήγησης ζητά μια ιστοσελίδα, ο διακομιστής δεν την αποστέλλει απευθείας byte by byte. Αντ 'αυτού, το στέλνει σε συμπιεσμένη κατάσταση με βάση τις αποδεκτές κωδικοποιήσεις του προγράμματος περιήγησης. Κυρίως όλοι χρησιμοποιούν σήμερα το Gzip και μπορείτε να ρωτήσετε γιατί; Επειδή ήταν εδώ και περισσότερο από μια δεκαετία.

Εδώ λοιπόν έρχεται το Brotli, που είναι ο τελευταίος αλγόριθμος κωδικοποίησης που αναπτύχθηκε από την Google. Το Brotli είναι ~ 20% πιο αποτελεσματικό από το Gzip. Απλώς λάβετε υπόψη ότι πρέπει να στείλετε περιεχόμενο στο Gzip όπου δεν υποστηρίζεται το Brotli. Το Brotli λειτουργεί καλύτερα με στατικά αρχεία και όχι με δυναμικό περιεχόμενο.

Επίσης, βεβαιωθείτε ότι έχετε ενεργοποιήσει τον τύπο Brotli για δεδομένα API JSON μόνο όταν το υποστηρίζει η βιβλιοθήκη HTTP από τον πελάτη σας. Για παράδειγμα, η βιβλιοθήκη Axios δεν υποστηρίζει ακόμα την κωδικοποίηση Brotli.

http { ... # Gzip Settings gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 32 16k; gzip_http_version 1.1; gzip_min_length 250; gzip_types image/jpeg image/bmp image/svg+xml text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon; # Brotli Settings brotli on; brotli_comp_level 4; brotli_buffers 32 8k; brotli_min_length 100; brotli_static on; brotli_types image/jpeg image/bmp image/svg+xml text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon; ... }

Μόλις προσθέσετε αυτές τις αλλαγές, μπορείτε να ελέγξετε ότι η κωδικοποίηση περιεχομένου εμφανίζεται brστις κεφαλίδες απόκρισης στα εργαλεία προγραμματιστή Chrome:

Βελτιώστε την ασφάλεια

Από προεπιλογή, το NGINX δεν διαθέτει όλες τις σημαντικές κεφαλίδες ασφαλείας που απαιτούνται, πράγμα που είναι αρκετά απλό. Αυτά αποτρέπουν τις επιθέσεις clickjacking, τις επιθέσεις scripting μεταξύ ιστότοπων και άλλες επιθέσεις με έγχυση κώδικα.

Strict-Transport-SecurityΗ κεφαλίδα είναι για HTTP Strict Transport Security (HSTS) που προστατεύει επίσης από επιθέσεις υποβάθμισης πρωτοκόλλου.

http { ... # security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; ... }

Βελτιστοποίηση SSL και περιόδων σύνδεσης

SSL: Χρησιμοποιήστε το στο TLS και απενεργοποιήστε το SSL (το SSL είναι αρκετά παλιό και ξεπερασμένο και έχει πολλές ευπάθειες). Βελτιστοποιήστε τις κρυπτογραφικές σουίτες, καθώς αποτελούν τον πυρήνα του TLS. Εδώ συμβαίνει η κρυπτογράφηση.

Session Cache: Η δημιουργία προσωρινής μνήμης παραμέτρων σύνδεσης TLS μειώνει τον αριθμό των χειραψιών και έτσι μπορεί να βελτιώσει την απόδοση της εφαρμογής σας. Η προσωρινή αποθήκευση ρυθμίζεται χρησιμοποιώντας ssl_session_cacheοδηγία.

Εισιτήρια Συνεδρίας: Τα εισιτήρια συνεδρίας είναι μια εναλλακτική λύση στην προσωρινή μνήμη περιόδου λειτουργίας Σε περίπτωση προσωρινής αποθήκευσης περιόδου λειτουργίας, οι πληροφορίες σχετικά με τη συνεδρία αποθηκεύονται στο διακομιστή.

OSCP: Για να υπάρχει ασφαλής σύνδεση με διακομιστή, ο πελάτης πρέπει να επαληθεύσει το πιστοποιητικό που παρουσίασε ο διακομιστής. Προκειμένου να επαληθευτεί ότι το πιστοποιητικό δεν ανακαλείται, ο πελάτης (πρόγραμμα περιήγησης) θα επικοινωνήσει με τον εκδότη του πιστοποιητικού. Αυτό προσθέτει λίγο περισσότερη επιβάρυνση στην αρχικοποίηση της σύνδεσης (και έτσι ο χρόνος φόρτωσης της σελίδας μας).

Χρησιμοποιήστε αυτές τις οδηγίες στη διαμόρφωση NGINX και είστε έτοιμοι για βελτιστοποίηση SSL.

http { ... # SSL Settings ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GC$ # Optimize session cache ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; # Enable session tickets ssl_session_tickets on; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s; resolver_timeout 2s; ... }

Βελτίωση απόδοσης: Υποστήριξη HTTP / 2

Το HTTP / 2 έχει πολλά οφέλη σε σχέση με το HTTP, όπως το να επιτρέπει στο πρόγραμμα περιήγησης να κάνει λήψη αρχείων παράλληλα και να επιτρέπει στον διακομιστή να προωθεί πόρους, μεταξύ άλλων. Το μόνο που έχετε να κάνετε είναι να αντικαταστήσετε httpμε http2το προεπιλεγμένο μπλοκ server σας. Αυτό είναι, και έχετε πολλά και πολλά οφέλη.

server{ ... listen 443 http2 default_server; listen [::]:443 http2 default_server; server_name example.com; ... }

Πληκτρολογήστε αυτήν την εντολή curl -I -L //example.comκαι επαληθεύστε την απόκριση.

HTTP/2 200 server: nginx date: Wed, 18 Jul 2018 02:13:32 GMT content-type: text/html; charset=utf-8 content-length: 216641 vary: Accept-Encoding ....

Μειώστε το Scrapping / Attacks

Limiting the requests to the server is critical, as this can easily deplete the resources and can result in huge billings. This is also important to fend off those who want to scrape and attack our servers. There are basically three types of directives:

  • Request Limiting limit_req : Limit the number of requests per IP
  • Connections Limiting limit_conn : Limit the number of Connections per IP
  • Bandwidth/Rate Limiting limit_rate : Limit the bandwidth rate of data being sent

With the below directive, you can rest easy:

http { ... # Limits limit_req_log_level warn; limit_req_zone $binary_remote_addr zone=reqlimit:10m rate=10r/m; limit_conn_zone $binary_remote_addr zone=connlimit:100m; limit_conn servers 1000; # Simultaneous Connections ... }
... server { ... location /api/ { # Rate Limiting limit_req zone=reqlimit burst=20; # Max burst of request limit_req_status 460; # Status to send # Connections Limiting limit_conn connlimit 20; # Number of downloads per IP # Bandwidth Limiting limit_rate 4096k; # Speed limit (here is on kb/s) } ... }

Client-side Caching

Caching static files on the browser is easy, and it saves lot of requests to the server. All you have to do is add these two code blocks and specify the expiration as you please. You can include any other static file extension you deem worthy of caching.

server { ... location / { ... ... } ... ... location ~* \.(jpg|jpeg|png|gif|ico)$ { expires 30d; } location ~* \.(css|js)$ { expires 7d; } ... }

Microcaching

If you haven’t heard about this until now, then you are in luck today! Microcaching is a caching technique in which content is cached for a very short period of time, perhaps as little as 1 second. This effectively means that updates to the site are delayed by no more than a second, which in many cases is perfectly acceptable. This is particularly useful for API responses which are the same for all users.

Use these directives to set microcaching with the path at /tmp/cacheapi with 100MB cache with a max size of 1GB of cache folder that updates cache in the background. Learn more about it here and here.

proxy_cache_path /tmp/cacheapi levels=1:2 keys_zone=microcacheapi:100m max_size=1g inactive=1d use_temp_path=off; ... server { ... location /api/ { # Micro caching proxy_cache microcacheapi; proxy_cache_valid 200 1s; proxy_cache_use_stale updating; proxy_cache_background_update on; proxy_cache_lock on; ... ... } ... }
http { ... add_header X-Cache-Status $upstream_cache_status; ... }

SSL Certificate

Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates. This enables encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps.

Install LetsEnctypt:

sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-nginx

Create a LetsEncrypt SSL certificate with this command:

sudo certbot --nginx -d example.com -d www.example.com

and then add these certificates to your domain config file like this:

server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; ... ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ... }

Redirect WWW

Google prefers that you choose a domain with www instead of without. It’s better to choose the naked domain as its smaller and removes the redundant www . You can now redirect all www users to your naked domain by adding these below directives.

server { ... ... } server { listen 80; listen [::]:80; server_name example.com; return 301 //$server_name$request_uri; } server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.com; return 301 //example.com$request_uri; }

Pagespeed Module

Pagespeed Module is a gem unknown to many. It was originally a Google Project which is now part of Apache Incubator. Pagespeed can automatically take care of almost all the known ways to improve performance on your website.

Installor Upgrade NGINX with Pagespeed. This is not an easy task, and that’s why I have saved it for last. Follow these instructions, and you should be able to do it without any hastle. Once you’re done, all you need to do is enable it and voilà!

server{ ... # Pagespeed Module pagespeed on; pagespeed FileCachePath /var/cache/ngx_pagespeed_cache; location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; } location ~ "^/pagespeed_static/" { } location ~ "^/ngx_pagespeed_beacon$" { } pagespeed RewriteLevel PassThrough; pagespeed EnableCachePurge on; pagespeed PurgeMethod PURGE; pagespeed EnableFilters prioritize_critical_css; ... }

There are so many filters that you can enable, but just keep in mind that most of the modern frameworks like (Nuxt.js, Angular, Next.js and so on) have some of these optimisations as part of their build process, so this can be counterintuitive. Choose filters which you need and enable only them. This is not by any means an exhaustive set of filters, but would definitely take your site to 100/100 on pagespeed.

pagespeed EnableFilters rewrite_css; pagespeed EnableFilters collapse_whitespace,remove_comments; pagespeed EnableFilters flatten_css_imports; pagespeed EnableFilters combine_css; pagespeed EnableFilters combine_javascript; pagespeed EnableFilters defer_javascript; pagespeed EnableFilters extend_cache; pagespeed EnableFilters pedantic; pagespeed EnableFilters inline_google_font_css; pagespeed FetchHttps enable; pagespeed EnableFilters inline_css,move_css_above_scripts; pagespeed EnableFilters inline_javascript; pagespeed EnableFilters inline_import_to_link; pagespeed EnableFilters lazyload_images; pagespeed EnableFilters insert_dns_prefetch; pagespeed EnableFilters inline_preview_images; pagespeed EnableFilters resize_mobile_images; pagespeed EnableFilters rewrite_images; pagespeed EnableFilters responsive_images,resize_images; pagespeed EnableFilters responsive_images_zoom; pagespeed EnableFilters rewrite_javascript; pagespeed EnableFilters rewrite_style_attributes,convert_meta_tags;

You can read more about different types of filters available here.

So the final NGINX config and domain config looks something like this:

//gist.github.com/1hakr/01cb00dfce8c92a15c0d9faee9052042

Now all you have to do is reload your NGINX config file by typing the below commands and you have supercharged your NGINX server:

sudo nginx -t sudo systemctl restart nginx

Pro Tip: If you find this article beyond your reach, then there is a simple website which can get the final config file for you: check out NGINX Config.

I hope you like this NGINX config and are able to supercharge your web apps. Do you already use something similar or have a different opinion altogether? Let me know in the comments.

This is my new microstartup, VisaList, where I have applied these optimisations. It can help you find visa requirements for all countries in the world in a simple and useful way.

Find countries to visit across the world

Search from list of countries your can travel with Visa free, Visa on arrival and other requirements from more than…

visalist.io

Όλοι οι λαοί! Αυτή είναι η αποσύνδεση του HaKr . Ευχαριστούμε που διαβάσατε και αν το βρήκατε χρήσιμο κάντε κλικ; να προτείνουν αυτό το άρθρο σε άλλους, ώστε να μπορούν να το βρουν επίσης.

Χτίζω microstartups ενώ ταξιδεύετε, όταν μπορώ. Αν βρείτε αυτό το είδος ενδιαφέροντος, μπορείτε να με ακολουθήσετε στο Twitter και να δείτε τη δουλειά μου ανοιχτού κώδικα στο GitHub.