NGINX與HAPI FHIR整合
===
由於HAPI FHIR定位為開源軟體,因此就商業考量角度來看,community版本缺乏某些實際上線需要的功能,例如負載平衡、效能、監控、Log管理等。
改善方向可思考以下幾個方式:
1. 使用商業版:Smile Digial Health `https://www.smiledigitalhealth.com/`提供商業版本之HAPI FHIR。
2. 自行修改HAPI FHIR原始碼。
3. 整合其他開源軟體功能,如本文所敘述之NGINX。
NGINX使用案例如下圖所示:

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`.
```mermaid
graph TD;
main-->events;
main-->http;
http-->server;
server-->location;
```
* The rest of a line after the # sign is considered a comment.
Load Balancer設定
---

預計之系統架構如上圖所示,所有模組都是容器化,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;
}
}
}
```