Apa itu Layanan Mikro?
Layanan mikro adalah arsitektur yang semakin populer untuk membangun aplikasi skala besar. Daripada menggunakan satu basis kode monolitik, aplikasi dipecah menjadi kumpulan komponen yang lebih kecil yang disebut layanan mikro. Pendekatan ini menawarkan beberapa manfaat, termasuk kemampuan untuk menskalakan layanan mikro individu, menjaga basis kode lebih mudah dipahami dan diuji, dan memungkinkan penggunaan bahasa pemrograman, database, dan alat lain yang berbeda untuk setiap layanan mikro.
Docker adalah alat yang sangat baik untuk mengelola dan menerapkan layanan mikro. Setiap layanan mikro dapat dipecah lebih lanjut menjadi proses yang berjalan di wadah Docker terpisah, yang dapat ditentukan dengan file konfigurasi Dockerfiles dan Docker Compose. Dikombinasikan dengan alat penyediaan seperti Kubernetes, setiap layanan mikro kemudian dapat dengan mudah digunakan, diskalakan, dan dikolaborasikan oleh tim pengembang. Menentukan lingkungan dengan cara ini juga memudahkan untuk menautkan layanan mikro bersama-sama untuk membentuk aplikasi yang lebih besar.
Panduan ini menunjukkan cara membuat dan menerapkan layanan mikro contoh menggunakan Docker dan Docker Compose.
Sebelum Anda Mulai
-
Jika Anda belum melakukannya, buat akun Linode dan Compute Instance. Lihat panduan Memulai Linode dan Membuat Instans Komputasi.
-
Ikuti panduan Menyiapkan dan Mengamankan Instans Komputasi untuk memperbarui sistem Anda. Anda mungkin juga ingin mengatur zona waktu, mengkonfigurasi nama host Anda, membuat akun pengguna terbatas, dan memperkuat akses SSH.
Catatan Panduan ini ditulis untuk pengguna non-root. Perintah yang memerlukan hak istimewa yang lebih tinggi diawali dengansudo
. Jika Anda tidak terbiasa dengansudo
perintah, Anda dapat memeriksa panduan Pengguna dan Grup kami.
Instal Docker
Untuk menginstal Docker CE (Edisi Komunitas), ikuti petunjuk dalam salah satu panduan di bawah ini:
-
Menginstal dan Menggunakan Docker di Ubuntu dan Debian
-
Memasang dan Menggunakan Docker di CentOS dan Fedora
Untuk petunjuk lengkap tentang distribusi Linux lainnya, lihat bagian Instal Docker Engine dari dokumentasi resmi Docker.
Instal Docker Compose
-
Unduh versi terbaru Docker Compose. Periksa halaman rilis dan ganti
1.25.4
pada perintah di bawah ini dengan versi yang ditandai sebagai Rilis terbaru :sudo curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
-
Setel izin file:
sudo chmod +x /usr/local/bin/docker-compose
Siapkan Lingkungan
Bagian ini menggunakan Dockerfiles untuk mengonfigurasi image Docker. Untuk informasi selengkapnya tentang sintaks Dockerfile dan praktik terbaik, lihat panduan Cara Menggunakan Dockerfiles kami dan panduan Praktik Terbaik Dockerfile Docker.
-
Buat direktori untuk layanan mikro:
mkdir flask-microservice
-
Buat struktur direktori untuk komponen layanan mikro dalam direktori baru:
cd flask-microservice mkdir nginx postgres web
NGINX
-
Di dalam
nginx
. yang baru subdirektori, buat file Docker untuk gambar NGINX:- File:nginx /Dockerfile
1 2
from nginx:alpine COPY nginx.conf /etc/nginx/nginx.conf
-
Buat
nginx.conf
direferensikan di Dockerfile:- File:/ nginx/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
user nginx; worker_processes 1; error_log /dev/stdout info; error_log off; pid /var/run/nginx.pid; events { worker_connections 1024; use epoll; multi_accept on; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /dev/stdout main; access_log off; keepalive_timeout 65; keepalive_requests 100000; tcp_nopush on; tcp_nodelay on; server { listen 80; proxy_pass_header Server; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # app comes from /etc/hosts, Docker added it for us! proxy_pass http://flaskapp:8000/; } } }
PostgreSQL
Gambar PostgreSQL untuk layanan mikro ini akan menggunakan postgresql
resmi image di Docker Hub, jadi tidak diperlukan Dockerfile.
Di postgres
subdirektori, buat init.sql
berkas:
- File:postgres /init.sql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SET check_function_bodies = false; SET client_min_messages = warning; SET row_security = off; CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; SET search_path = public, pg_catalog; SET default_tablespace = ''; SET default_with_oids = false; CREATE TABLE visitors ( site_id integer, site_name text, visitor_count integer ); ALTER TABLE visitors OWNER TO postgres; COPY visitors (site_id, site_name, visitor_count) FROM stdin; 1 linodeexample.com 0 \.
Hati-hati Di Baris 22 dari init.sql
, pastikan editor teks Anda tidak mengonversi tab menjadi spasi. Aplikasi tidak akan berfungsi tanpa tab di antara entri di baris ini.
Web
web
gambar akan menampung contoh aplikasi Flask. Tambahkan file berikut ke web
direktori untuk menyiapkan aplikasi:
-
Buat
.python-version
file untuk menentukan penggunaan Python 3.6:echo "3.6.0" >> web/.python-version
-
Buat Dockerfile untuk
web
gambar:- File:web /Dockerfile
1 2 3 4 5 6 7 8 9 10
from python:3.6.2-slim RUN groupadd flaskgroup && useradd -m -g flaskgroup -s /bin/bash flask RUN echo "flask ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers RUN mkdir -p /home/flask/app/web WORKDIR /home/flask/app/web COPY requirements.txt /home/flask/app/web RUN pip install --no-cache-dir -r requirements.txt RUN chown -R flask:flaskgroup /home/flask USER flask ENTRYPOINT ["/usr/local/bin/gunicorn", "--bind", ":8000", "linode:app", "--reload", "--workers", "16"]
-
Buat
web/linode.py
dan tambahkan contoh skrip aplikasi:- File:web /linode.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
from flask import Flask import logging import psycopg2 import redis import sys app = Flask(__name__) cache = redis.StrictRedis(host='redis', port=6379) # Configure Logging app.logger.addHandler(logging.StreamHandler(sys.stdout)) app.logger.setLevel(logging.DEBUG) def PgFetch(query, method): # Connect to an existing database conn = psycopg2.connect("host='postgres' dbname='linode' user='postgres' password='linode123'") # Open a cursor to perform database operations cur = conn.cursor() # Query the database and obtain data as Python objects dbquery = cur.execute(query) if method == 'GET': result = cur.fetchone() else: result = "" # Make the changes to the database persistent conn.commit() # Close communication with the database cur.close() conn.close() return result @app.route('/') def hello_world(): if cache.exists('visitor_count'): cache.incr('visitor_count') count = (cache.get('visitor_count')).decode('utf-8') update = PgFetch("UPDATE visitors set visitor_count = " + count + " where site_id = 1;", "POST") else: cache_refresh = PgFetch("SELECT visitor_count FROM visitors where site_id = 1;", "GET") count = int(cache_refresh[0]) cache.set('visitor_count', count) cache.incr('visitor_count') count = (cache.get('visitor_count')).decode('utf-8') return 'Hello Linode! This page has been viewed %s time(s).' % count @app.route('/resetcounter') def resetcounter(): cache.delete('visitor_count') PgFetch("UPDATE visitors set visitor_count = 0 where site_id = 1;", "POST") app.logger.debug("reset visitor count") return "Successfully deleted redis and postgres counters"
-
Tambahkan
requirements.txt
file dengan dependensi Python yang diperlukan:- File:web /requirements.txt
1 2 3 4
flask gunicorn psycopg2-binary redis
Tulisan Docker
Docker Compose akan digunakan untuk menentukan koneksi antara container dan pengaturan konfigurasinya.
Buat docker-compose.yml
file di flask-microservice
direktori dan tambahkan berikut ini:
- File:buruh pelabuhan -compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
version: '3' services: # Define the Flask web application flaskapp: # Build the Dockerfile that is in the web directory build: ./web # Always restart the container regardless of the exit status; try and restart the container indefinitely restart: always # Expose port 8000 to other containers (not to the host of the machine) expose: - "8000" # Mount the web directory within the container at /home/flask/app/web volumes: - ./web:/home/flask/app/web # Don't create this container until the redis and postgres containers (below) have been created depends_on: - redis - postgres # Link the redis and postgres containers together so they can talk to one another links: - redis - postgres # Pass environment variables to the flask container (this debug level lets you see more useful information) environment: FLASK_DEBUG: 1 # Deploy with three replicas in the case one of the containers fails (only in Docker Swarm) deploy: mode: replicated replicas: 3 # Define the redis Docker container redis: # use the redis:alpine image: https://hub.docker.com/_/redis/ image: redis:alpine restart: always deploy: mode: replicated replicas: 3 # Define the redis NGINX forward proxy container nginx: # build the nginx Dockerfile: http://bit.ly/2kuYaIv build: nginx/ restart: always # Expose port 80 to the host machine ports: - "80:80" deploy: mode: replicated replicas: 3 # The Flask application needs to be available for NGINX to make successful proxy requests depends_on: - flaskapp # Define the postgres database postgres: restart: always # Use the postgres alpine image: https://hub.docker.com/_/postgres/ image: postgres:alpine # Mount an initialization script and the persistent postgresql data volume volumes: - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql - ./postgres/data:/var/lib/postgresql/data # Pass postgres environment variables environment: POSTGRES_PASSWORD: linode123 POSTGRES_DB: linode # Expose port 5432 to other Docker containers expose: - "5432"
Uji Layanan Mikro
-
Gunakan Docker Compose untuk membuat semua gambar dan memulai layanan mikro:
cd flask-microservice/ && docker-compose up
Anda akan melihat semua layanan dimulai di terminal Anda.
-
Buka jendela terminal baru dan buat permintaan ke aplikasi contoh:
curl localhost
Hello Linode! This page has been viewed 1 time(s).
-
Setel ulang penghitung klik halaman:
curl localhost/resetcounter
Successfully deleted redis and postgres counters
-
Kembali ke jendela terminal tempat Docker Compose mulai melihat log keluar standar:
flaskapp_1 | DEBUG in linode [/home/flask/app/web/linode.py:56]: flaskapp_1 | reset visitor count
Menggunakan Container dalam Produksi:Praktik Terbaik
Kontainer yang digunakan dalam contoh layanan mikro dimaksudkan untuk menunjukkan praktik terbaik berikut untuk menggunakan kontainer dalam produksi:
Wadah harus:
-
Efemeral :Seharusnya mudah untuk menghentikan, menghancurkan, membangun kembali, dan menerapkan ulang container dengan penyiapan dan konfigurasi minimal.
Layanan mikro Flask adalah contoh ideal untuk ini. Seluruh layanan mikro dapat dinaikkan atau diturunkan menggunakan Docker Compose. Tidak ada konfigurasi tambahan yang diperlukan setelah container berjalan, yang memudahkan untuk memodifikasi aplikasi.
-
Sekali pakai :Idealnya, wadah tunggal apa pun dalam aplikasi yang lebih besar harus dapat gagal tanpa memengaruhi kinerja aplikasi. Menggunakan
restart: on-failure
opsi didocker-compose.yml
file, serta memiliki jumlah replika, memungkinkan beberapa wadah dalam contoh layanan mikro gagal dengan baik saat masih melayani aplikasi web – tanpa penurunan ke pengguna akhir.Catatan Arahan jumlah replika hanya akan efektif bila konfigurasi ini diterapkan sebagai bagian dari aDocker Swarm, yang tidak tercakup dalam panduan ini.
-
Cepat untuk memulai :Menghindari langkah penginstalan tambahan di file Docker, menghapus dependensi yang tidak diperlukan, dan membangun image target yang dapat digunakan kembali adalah tiga langkah terpenting dalam membuat aplikasi web yang memiliki waktu inisialisasi cepat di dalam Docker. Aplikasi contoh menggunakan Dockerfiles yang singkat, ringkas, dan telah dibuat sebelumnya untuk meminimalkan waktu inisialisasi.
-
Cepat berhenti :Memvalidasi bahwa
docker kill --signal=SIGINT {APPNAME}
menghentikan aplikasi dengan anggun. Ini, bersama dengan kondisi restart dan kondisi replika, akan memastikan bahwa ketika container gagal, container akan dikembalikan online secara efisien. -
Ringan :Gunakan wadah dasar terkecil yang menyediakan semua utilitas yang diperlukan untuk membangun dan menjalankan aplikasi Anda. Banyak gambar Docker didasarkan pada Alpine Linux, distribusi Linux yang ringan dan sederhana yang hanya membutuhkan 5MB dalam gambar Docker. Menggunakan distro kecil menghemat jaringan dan overhead operasional, dan sangat meningkatkan kinerja container. Aplikasi contoh menggunakan gambar alpine jika berlaku (NGINX, Redis, dan PostgreSQL), dan gambar dasar python-slim untuk aplikasi Gunicorn / Flask.
-
Tanpa kewarganegaraan :Karena bersifat sementara, container biasanya tidak boleh mempertahankan statusnya. Status aplikasi harus disimpan dalam volume data persisten yang terpisah, seperti halnya penyimpanan data PostgreSQL layanan mikro. Penyimpanan nilai kunci Redis memang memelihara data di dalam wadah, tetapi data ini tidak penting untuk aplikasi; penyimpanan Redis akan gagal kembali dengan anggun ke database jika wadah tidak dapat merespons.
-
Portabel :Semua dependensi aplikasi yang diperlukan untuk runtime container harus tersedia secara lokal. Semua contoh dependensi layanan mikro dan skrip startup disimpan di direktori untuk setiap komponen. Ini dapat diperiksa ke dalam kontrol versi, sehingga memudahkan untuk berbagi dan menerapkan aplikasi.
-
Modular :Setiap wadah harus memiliki satu tanggung jawab dan satu proses. Dalam layanan mikro ini, setiap proses utama (NGINX, Python, Redis, dan PostgreSQL) dikerahkan dalam wadah terpisah.
-
Mencatat Log :Semua kontainer harus masuk ke
STDOUT
. Keseragaman ini memudahkan untuk melihat log untuk semua proses dalam satu aliran. -
Tangguh :Aplikasi contoh memulai ulang wadahnya jika keluar karena alasan apa pun. Ini membantu memberikan aplikasi Dockerized Anda ketersediaan dan kinerja yang tinggi, bahkan selama periode pemeliharaan.
Informasi Lebih Lanjut
Anda mungkin ingin berkonsultasi dengan sumber daya berikut untuk informasi tambahan tentang topik ini. Meskipun ini disediakan dengan harapan dapat bermanfaat, harap perhatikan bahwa kami tidak dapat menjamin keakuratan atau ketepatan waktu materi yang dihosting secara eksternal.
- Repositori Github untuk Contoh Layanan Mikro
- Menggunakan Container untuk Membangun Arsitektur Layanan Mikro