Try   HackMD

NGINX與HAPI FHIR整合

由於HAPI FHIR定位為開源軟體,因此就商業考量角度來看,community版本缺乏某些實際上線需要的功能,例如負載平衡、效能、監控、Log管理等。

改善方向可思考以下幾個方式:

  1. 使用商業版:Smile Digial Health https://www.smiledigitalhealth.com/提供商業版本之HAPI FHIR。
  2. 自行修改HAPI FHIR原始碼。
  3. 整合其他開源軟體功能,如本文所敘述之NGINX。

NGINX使用案例如下圖所示:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

NGINX運作(https://nginx.org/en/docs/beginners_guide.html):

  • nginx has one master process and several worker processes.
  • The main purpose of the master process is to read and evaluate configuration, and maintain worker processes.
  • Worker processes do actual processing of requests.
  • nginx employs event-based model and OS-dependent mechanisms to efficiently distribute requests among worker processes.
  • The number of worker processes is defined in the configuration file and may be fixed for a given configuration or automatically adjusted to the number of available CPU cores.

NGING設定(https://nginx.org/en/docs/beginners_guide.html):

  • By default, the configuration file is named nginx.conf and placed in the directory /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx.
  • nginx consists of modules which are controlled by directives specified in the configuration file.
  • Directives are divided into simple directives and block directives.
    • A simple directive consists of the name and parameters separated by spaces and ends with a semicolon (;).
    • A block directive has the same structure as a simple directive, but instead of the semicolon it ends with a set of additional instructions surrounded by braces ({ and }).
  • If a block directive can have other directives inside braces, it is called a context (examples: events, http, server, and location).
  • Directives placed in the configuration file outside of any contexts are considered to be in the main context.
  • The events and http directives reside in the main context, server in http, and location in server.

main

events

http

server

location

  • The rest of a line after the # sign is considered a comment.

Load Balancer設定

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

預計之系統架構如上圖所示,所有模組都是容器化,NGINX扮演Load Balancer角色,將外部的Request依照設定分配給後端HAPI FHIR。這不是最終的架構,下一階段將結合K8S,根據的效能需求,做即時的動態資源分配。

docker-compose檔

version: '3.7'

services:

  ngnix:
    container_name: nginx
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
    depends_on:
      - fhir1
      - fhir2

  db:
    container_name: bmaindb
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: hapipoc
      POSTGRES_USER: hapipoc
      POSTGRES_DB: hapi
    # not needed for networking between containers but here for troubleshooting
    ports:
      - "5433:5432"

  fhir1:
    container_name: bmainfhir1
    image: hapiproject/hapi:latest
    ports:
      - "8081:8080"
    environment:
      HAPI_FHIR_USERNAME : admin
      HAPI_FHIR_PASSWORD : admin
      profiles.active: r4
    configs:
      - source: hapi
        target: /app/config/application.yaml
    depends_on:
      - db

  fhir2:
    container_name: bmainfhir2
    image: hapiproject/hapi:latest
    ports:
      - "8082:8080"
    environment:
      HAPI_FHIR_USERNAME : admin
      HAPI_FHIR_PASSWORD : admin
      profiles.active: r4
    configs:
      - source: hapi
        target: /app/config/application.yaml
    depends_on:
      - db

configs:
  hapi:
     file: ./hapi.application.yaml

nginx.conf檔

events { worker_connections 1024; }

http {

    upstream api_servers {    # Create an upstream for the web servers
        server fhir1:8080;    # the first server
        server fhir2:8080;    # the second server
    }

    server {
        listen 80;

        location / {
            proxy_pass http://api_servers;  # load balance the traffic
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}