記帳專案說明
新專案說明
最近開新的專案,目前專案的系統架構和後端處理的差不多了,剩下前端的部分正在一邊學 react 一邊完成中,考慮到最近要開始找工作了,所以想說寫個部落格一邊介紹目前專案的架構與紀錄目前的狀態。
專案整體架構
在開始之前我們先發一張架構圖吧,接下來請把架構圖當成地圖開始冒險吧。
這次的專案主要是走雲原生的概念,下述我們分成基礎設施、前端、後端來聊吧
基礎建置
雲端服務廠商選擇: AWS
這個專案從剛開始設計就是預計上雲且使用的是 aws,主要有兩個點
- 我們家並沒有固定 IP ,如果要走地端的話勢必要使用到 DDNS ,那牽涉的範圍就會更廣了,因此決定直接上雲
- 根據網路上查到的資料,目前 aws 市佔 33% ,考慮到將來要找工作與方便尋找資料因此決定直接使用 aws
用到的 AWS 服務
接下來先概覽一下用到的服務與相關功能,下面會以使用者接觸到服務的順序來說明:
服務名稱 | 用途 |
---|---|
router53 | DNS, 用於將 domain 轉換成 IP, 我的 domain 也是在該服務購買的 |
彈性 IP | 當我們租了 AWS 的伺服器時是沒有對外 IP 的,因此我們需要透過彈性 IP 申請並且綁定到我們的 EC2 |
安全群組 | 連到伺服器的防火牆,可以設定每個 port 是否要開啟,並且設定白名單等 |
EC2 | 這個就是我租伺服器的本體,所有的服務與反向代理等都是放在這裡 |
EC2 建置了哪些服務
這邊會講一下我安裝與使用到哪些非我開發的服務
資料庫:
資料庫的部分我使用的是 mariaDB, 會選擇 mariaDB 的原因除了他是 MySQL 的分支之外,他的社群很活躍、穩定性也很高
catch:
catch 的部分我使用 redis ,主要適用於處理會需要經常取得資料或者不需要持久化的資料,目前我主要用於記錄使用者登入後的 token,由於採取的是前後端分離的架構,後端會需要頻繁的驗證 token 和透過 token 取得用者資訊,因此這部分得資料就放在 redis,更詳細的使用邏輯將會在後面提到後端的時候說明。
SSL:
這個專案的 SSL 主要用於 https 連線,這部分是使用 Let's Encrypt 家的憑證。
會用 Let's Encrypt 的原因最主要是免費和自動化申請,如果考慮到成本的話很建議大家可以考慮用他家的 SSL 憑證,且該贊助商有 Google, Mozilla, AWS 等公司,因此可以安心使用。
nginx反向代理
這邊需要先說一下我服務的 domain 設計,我的做法如同 google 等廠商一樣,不同的服務會有各自的 domain (目前主要是使用者管理服務和記帳服務),然後因為前端和後端是獨立不同的服務,所以可能還需要處理 CORS 問題,。
這時候就是 nginx 登場的時候了,nginx 可以根據不同的 domain 和 path 將 request/response 導向不同 port 號甚至是不同的機器,這就是反向代理,另外 https 的 SSL 的部分也是由 nginx 管理,因此將來如果要換憑證的話,也只要處理 nginx 就好了,會簡單很多。
nginx用於前端
前面有提到前端的部分也是獨立的服務,這部分我也是透過 nginx 讓靜態網頁或 CSR 的前端網頁可以獨立運作。
喝個水,聊一下走雲原生的原因
接下來後續要聊到的服務,和前面有提到當初規劃的時候就是想要走雲原生有關,走雲原生一定會需要考慮到以下的幾個點:
- 微服務架構
- 容器化
- 持續交付
- 自動化基礎設施
那為什麼要走雲原生:
主要第一點是我個人比較喜歡微服務架構,當我們將大型服務拆開來的話可以用更簡單的方式去觀察我們的功能,甚至當我們發現特定功能會有很多人使用的話可以很輕鬆的部署多個一樣服務之後透過 loadbalance 分散效能需求,同時如果要更新部署的話也可以不用停止整個應用程式會用到的服務也可以更新特定功能。
容器化和持續交付及自動化基礎設施的部分,主要讓我本來需要花費許多時間建置服務、部署等重複性工作可以自動化的完成。
像過去剛開始學習 AWS 的時候把伺服器環境用壞好幾次,每次都是透過自動化基礎設施快速建置一個新的伺服器。
聊完要走雲原生之後我們繼續聊基礎建置吧
docker:
docker 應該是目前處理容器化的最直覺想到的工具,目前除了 docker 之外容器化也有其他選擇,但考慮到通用性與社群之後就決定使用 docker 了。
目前反向代理、
docker compose:
在決定容器化之後我們要考慮的是如何自動化管理容器(比如容器狀態管理、自動重新啟動等),目前主流的應該是 K8s 與 docker compose ,考慮到 K8s 的學習曲線比較陡以及目前的 side project 尚未完成根本沒有流量,因此決定使用 docker compose 就好了,目前主要用於 CI/CD 狀態管裡和容器掛掉之後的自動重啟(但目前還沒有遇到自動重啟的機會)
CI/CD
CI/CD 的部分是使用 jenkins 並且搭配 jenkins 的 pipLine 達成,說實在的自動話部署真的很爽,當前自動化部署後端流程是: git pull 新的 test 分支 -> gradle 編譯 bootJar -> 生成存在於在宿主主機的 docker image -> 啟動容器 -> 保留 bootJar 的 jar 檔
前端的部分與後端大同小異,只是 gradle 編譯 bootJar 改成編譯 react + typescript 而已
只是目前還沒有達到完成體,當前是將宿主主機的 docker 前端和後端與 jenkins 共用,之後可能會租 aws 的 docker image 私有庫服務,流程將會是把 生成存在於在宿主主機的 docker image 改成存到 aws 的 docker image 私有庫,最後透過 ssh 連線操作宿主主機將 docker image pull 下來之後部署。
前端
前端的部分是使用 react 搭配 typescript 開發,技術選型會使用 react 主要是我自己目前會使用 vue3 開發前端,但還不會 react 和 typescript ,因此想說透過這次的 Side project 開發多學一些技術,不過的確或許該有一個專案用 vue3 來寫或許會比較方便面試。
前端的部分由於我只有自己一個人要做出漂亮的畫面實在有點難,因此有使用 MUI 這個 design system 下面截圖是目前做完的登入頁面,至於記帳頁面目前還在開發中
後端
後端的部分使用 java 開發,主要用到的框架有以下:
框架名稱 | 用途 |
---|---|
gradle | 依賴管理與打包編譯等的工具 |
springBoot | 後端服務框架 |
spring task | 處理定時服務 |
spring security | 用於處理登入和使用者權限管理 |
mybatis | 用於處理持久層工具 |
junit | 用於單元測試 |
mockito | 用於單元測試中 mock 的部分 |
spring doc | 用於生成 swagger 畫面,相關截圖可見下圖 |
登入機制
最後的最後想要聊一下架構圖中箭頭的部分。
箭頭的部分是登入流程,由於後面想要玩 spring ai,考慮到時候還要重寫一次登入與註冊功能,因此將登入功能拉出來,這個做法有參考 oauth,但沒有使用到 jwt 和多個 api 取得資訊,而是直接去 redis 取資料。
以上就是這次新 side project 的內容介紹,如果有任何覺得更好的做法歡迎在下面留言交流喔,考慮到單純的文字說明可能不更清楚,因此在最下面有放循序圖,還請大家參考看看^^
最下面的循序圖是:
留言
張貼留言