首頁 後端開發 Golang 使用 Go、PostgreSQL、Google Cloud 和 CockroachDB 建立 API

使用 Go、PostgreSQL、Google Cloud 和 CockroachDB 建立 API

Oct 24, 2024 am 07:02 AM

我使用 Go 和 PostgreSQL 建立了一個 API,使用 Google Cloud Run、Cloud Build、Secret Manager 和 ArtifactRegistry 設定了 CI/CD 管道,並將 Cloud Run 實例連接到 CockroachDB。

此API基於遊戲《核心危機:最終幻想VII》,模擬「物質融合」。本文的目標受眾是只想了解如何建置和部署 API 的開發人員。我還有另一篇文章,其中討論了我在從事該專案時學到的所有內容、哪些內容不起作用,以及理解和翻譯遊戲的材質融合規則(連結即將推出)。

方便參考的鏈接

  • GitHub 儲存庫與自述文件
  • Swagger (OpenAPI) 文件與測驗
  • 公共郵差收藏
  • 領域模型來源

API目標

3 個端點 - 健康檢查 (GET)、所有材料清單 (GET) 和模擬材料融合 (POST)

領域模型

物質(單數和複數)是一個水晶球,作為魔法的來源。遊戲中有 144 種不同的材質,大致分為 4 類:「魔法」、「指令」、「支援」和「獨立」。然而,為了弄清楚物質融合的規則,根據它們的融合行為,更容易有32個內部類別,以及這些類別內的8個等級(參見參考資料) .

一種材料在使用一定時間後就會變得「精通」。持續時間在這裡並不重要。

最重要的是,兩種材質可以融合產生一種新材質。融合規則受以下因素影響:

  • 是否掌握其中一種或兩種材料。
  • 哪一種材料先出現(如 X Y 不一定等於 Y X)。
  • 材質內部類別。
  • 材質等級。

Building an API with Go, PostgreSQL, Google Cloud and CockroachDB

並且有許多例外,其中一些規則具有 3 層嵌套的 if-else 邏輯。這消除了在資料庫中建立一個簡單表格並將 1000 條規則儲存到其中的可能性,或想出一個公式來規則所有規則的可能性。

簡而言之,我們需要:

  1. 一個表材質,其中包含列name(string)、materia_type(ENUM)(32 個內部類別)、grade(integer)、display_materia_type(ENUM)(遊戲中使用的4 個類別)、description(string) 和id(整數)作為自增主鍵。
  2. 封裝基本規則格式MateriaTypeA MateriaTypeB = MateriaTypeC的資料結構。
  3. 使用基本和複雜規則來決定輸出材料的內部類別和等級的代碼。

1. 設定本機 PostgreSQL 資料庫

理想情況下,您可以從網站本身安裝資料庫。但是pgAdmin工具因為某些原因無法連接到DB,所以我使用了Homebrew。

安裝

brew install postgresql@17
登入後複製
登入後複製
登入後複製

這將安裝一大堆 CLI 二進位檔案以幫助使用資料庫。

可選:將 /opt/homebrew/opt/postgresql@17/bin 加入 $PATH 變數。

# create the DB
createdb materiafusiondb
# step into the DB to perform SQL commands
psql materiafusiondb
登入後複製
登入後複製
登入後複製

建立使用者和權限

-- create an SQL user to be used by the Go server
CREATE USER go_client WITH PASSWORD 'xxxxxxxx';

-- The Go server doesn't ever need to add data to the DB. 
-- So let's give it just read permission.
CREATE ROLE readonly_role;
GRANT USAGE ON SCHEMA public TO readonly_role;

-- This command gives SELECT access to all future created tables. 
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly_role;

-- If you want to be more strict and give access only to tables that already exist, use this:
-- GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_role;

GRANT readonly_role TO go_client;
登入後複製
登入後複製
登入後複製

建立表

CREATE TYPE display_materia_type AS ENUM ('Magic', 'Command', 'Support', 'Independent');

CREATE TYPE materia_type AS ENUM ('Fire', 'Ice', 'Lightning', 'Restore', 'Full Cure', 'Status Defense', 'Defense', 'Absorb Magic', 'Status Magic', 'Fire & Status', 'Ice & Status', 'Lightning & Status', 'Gravity', 'Ultimate', 'Quick Attack', 'Quick Attack & Status', 'Blade Arts', 'Blade Arts & Status', 'Fire Blade', 'Ice Blade', 'Lightning Blade', 'Absorb Blade', 'Item', 'Punch', 'SP Turbo', 'HP Up', 'AP Up', 'ATK Up', 'VIT Up', 'MAG Up', 'SPR Up', 'Dash', 'Dualcast', 'DMW', 'Libra', 'MP Up', 'Anything');

CREATE TABLE materia (
    id integer NOT NULL,
    name character varying(50) NOT NULL,
    materia_type materia_type NOT NULL,
    grade integer NOT NULL,
    display_materia_type display_materia_type,
    description text
    CONSTRAINT materia_pkey PRIMARY KEY (id)
);

-- The primary key 'id' should auto-increment by 1 for every row entry.
CREATE SEQUENCE materia_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

ALTER SEQUENCE materia_id_seq OWNED BY materia.id;

ALTER TABLE ONLY materia ALTER COLUMN id SET DEFAULT nextval('materia_id_seq'::REGCLASS);
登入後複製
登入後複製

新增數據

建立包含表頭和資料的 Excel 工作表,並將其匯出為 CSV 檔案。然後運行命令:

COPY materia(name,materia_type,grade,display_materia_type,description) FROM
 '<path_to_csv_file>/materiadata.csv' DELIMITER ',' CSV HEADER;
登入後複製
登入後複製

2. 建立Go伺服器

使用 autostrada.dev 建立樣板程式碼。新增 api、postgresql、httprouter、env var config、tintedlogging、git、live reload、makefile 的選項。我們最後得到這樣的文件結構:

? codebase
├─ cmd
│  └─ api
│     ├─ errors.go
│     ├─ handlers.go
│     ├─ helpers.go
│     ├─ main.go
│     ├─ middleware.go
│     └─ server.go
├─ internal
│  ├─ database --- db.go
│  ├─ env --- env.go
│  ├─ request --- json.go
│  ├─ response --- json.go
│  └─ validator
│     ├─ helpers.go
│     └─ validators.go
├─ go.mod
├─ LICENSE
├─ Makefile
├─ README.md
└─ README.html
登入後複製
登入後複製

.env 文件

樣板產生器已建立程式碼來取得環境變數並將它們新增至程式碼中,但我們可以更輕鬆地追蹤和更新值。

建立 /.env 檔案。新增以下值:

HTTP_PORT=4444
DB_DSN=go_client:<password>@localhost:5432/materiafusiondb?sslmode=disable
API_TIMEOUT_SECONDS=5
API_CALLS_ALLOWED_PER_SECOND=1
登入後複製
登入後複製

新增 godotenv 庫:

go get github.com/joho/godotenv
登入後複製
登入後複製

將以下內容加入 main.go:

// At the beginning of main():
err := godotenv.Load(".env") // Loads environment variables from .env file
if err != nil { // This will be true in prod, but that's fine.
  fmt.Println("Error loading .env file")
}


// Modify config struct:
type config struct {
  baseURL string
  db      struct {
    dsn string
  }
  httpPort                 int
  apiTimeout               int
  apiCallsAllowedPerSecond float64
}

// Modify run() to use the new values from .env:
cfg.httpPort = env.GetInt("HTTP_PORT")
cfg.db.dsn = env.GetString("DB_DSN")
cfg.apiTimeout = env.GetInt("API_TIMEOUT_SECONDS")
cfg.apiCallsAllowedPerSecond = float64(env.GetInt("API_CALLS_ALLOWED_PER_SECOND"))

// cfg.baseURL = env.GetString("BASE_URL") - not required
登入後複製
登入後複製

中介軟體和路由

樣板已經有一個中間件可以從恐慌中恢復。我們將新增另外 3 個:Content-Type 檢查、速率限制和 API 逾時保護。

新增收費站庫:

go get github.com/didip/tollbooth
登入後複製
登入後複製

更新

func (app *application) contentTypeCheck(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  if r.Header.Get("Content-Type") != "application/json" {
   app.unsupportedMediaType(w, r)

   return
  }
  next.ServeHTTP(w, r)
 })
}


func (app *application) rateLimiter(next http.Handler) http.Handler {
 limiter := tollbooth.NewLimiter(app.config.apiCallsAllowedPerSecond, nil)
 limiter.SetIPLookups([]string{"X-Real-IP", "X-Forwarded-For", "RemoteAddr"})

 return tollbooth.LimitHandler(limiter, next)
}


func (app *application) apiTimeout(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  timeoutDuration := time.Duration(app.config.apiTimeout) * time.Second

  ctx, cancel := context.WithTimeout(r.Context(), timeoutDuration)
  defer cancel()

  r = r.WithContext(ctx)

  done := make(chan struct{})

  go func() {
   next.ServeHTTP(w, r)
   close(done)
  }()

  select {
  case <-done:
   return
  case <-ctx.Done():
   app.gatewayTimeout(w, r)
   return
  }
 })
}
登入後複製
登入後複製

中間件需要加入到路由中。它們可以添加到所有路由,也可以添加到特定路由。在我們的範例中,僅 POST 請求需要 Content-Type 檢查(即強制輸入標頭包含 Content-Type: application/json)。所以修改routes.go如下:

func (app *application) routes() http.Handler {
 mux := httprouter.New()

 mux.NotFound = http.HandlerFunc(app.notFound)
 mux.MethodNotAllowed = http.HandlerFunc(app.methodNotAllowed)

 // Serve the Swagger UI. Uncomment this line later
 // mux.Handler("GET", "/docs/*any", httpSwagger.WrapHandler)

 mux.HandlerFunc("GET", "/status", app.status)
 mux.HandlerFunc("GET", "/materia", app.getAllMateria)

 // Adding content-type check middleware to only the POST method
 mux.Handler("POST", "/fusion", app.contentTypeCheck(http.HandlerFunc(app.fuseMateria)))

 return app.chainMiddlewares(mux)
}

func (app *application) chainMiddlewares(next http.Handler) http.Handler {
 middlewares := []func(http.Handler) http.Handler{
  app.recoverPanic,
  app.apiTimeout,
  app.rateLimiter,
 }

 for _, middleware := range middlewares {
  next = middleware(next)
 }

 return next
}

登入後複製

錯誤處理

/api/errors.go 中加入以下方法來幫助中間件功能:

func (app *application) unsupportedMediaType(w http.ResponseWriter, r *http.Request) {
 message := fmt.Sprintf("The %s Content-Type is not supported", r.Header.Get("Content-Type"))
 app.errorMessage(w, r, http.StatusUnsupportedMediaType, message, nil)
}

func (app *application) gatewayTimeout(w http.ResponseWriter, r *http.Request) {
 message := "Request timed out"
 app.errorMessage(w, r, http.StatusGatewayTimeout, message, nil)
}
登入後複製

請求和響應結構文件

/api/dtos.go :

package main

// MateriaDTO provides Materia details - Name, Description and Type (Magic / Command / Support / Independent)
type MateriaDTO struct {
 Name        string `json:"name" example:"Thunder"`
 Type        string `json:"type" example:"Magic"`
 Description string `json:"description" example:"Shoots lightning forward dealing thunder damage."`
}

// StatusDTO provides status of the server
type StatusDTO struct {
 Status string `json:"Status" example:"OK"`
}

// ErrorResponseDTO provides Error message
type ErrorResponseDTO struct {
 Error string `json:"Error" example:"The server encountered a problem and could not process your request"`
}
登入後複製

/api/requests.go :

brew install postgresql@17
登入後複製
登入後複製
登入後複製

產生程式碼中的驗證器稍後將用於驗證融合端點的輸入欄位。

組合規則的資料結構

建立檔案 /internal/crisis-core-materia-fusion/constants.go

加入以下內容:

# create the DB
createdb materiafusiondb
# step into the DB to perform SQL commands
psql materiafusiondb
登入後複製
登入後複製
登入後複製

32 種 MateriaType 的完整清單可以在此處找到。

建立檔案 /internal/crisis-core-materia-fusion/models.go

加入以下內容:

-- create an SQL user to be used by the Go server
CREATE USER go_client WITH PASSWORD 'xxxxxxxx';

-- The Go server doesn't ever need to add data to the DB. 
-- So let's give it just read permission.
CREATE ROLE readonly_role;
GRANT USAGE ON SCHEMA public TO readonly_role;

-- This command gives SELECT access to all future created tables. 
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly_role;

-- If you want to be more strict and give access only to tables that already exist, use this:
-- GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_role;

GRANT readonly_role TO go_client;
登入後複製
登入後複製
登入後複製

完整的規則清單可以在這裡找到。

api/handlers.go 中材質的處理程序

CREATE TYPE display_materia_type AS ENUM ('Magic', 'Command', 'Support', 'Independent');

CREATE TYPE materia_type AS ENUM ('Fire', 'Ice', 'Lightning', 'Restore', 'Full Cure', 'Status Defense', 'Defense', 'Absorb Magic', 'Status Magic', 'Fire & Status', 'Ice & Status', 'Lightning & Status', 'Gravity', 'Ultimate', 'Quick Attack', 'Quick Attack & Status', 'Blade Arts', 'Blade Arts & Status', 'Fire Blade', 'Ice Blade', 'Lightning Blade', 'Absorb Blade', 'Item', 'Punch', 'SP Turbo', 'HP Up', 'AP Up', 'ATK Up', 'VIT Up', 'MAG Up', 'SPR Up', 'Dash', 'Dualcast', 'DMW', 'Libra', 'MP Up', 'Anything');

CREATE TABLE materia (
    id integer NOT NULL,
    name character varying(50) NOT NULL,
    materia_type materia_type NOT NULL,
    grade integer NOT NULL,
    display_materia_type display_materia_type,
    description text
    CONSTRAINT materia_pkey PRIMARY KEY (id)
);

-- The primary key 'id' should auto-increment by 1 for every row entry.
CREATE SEQUENCE materia_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

ALTER SEQUENCE materia_id_seq OWNED BY materia.id;

ALTER TABLE ONLY materia ALTER COLUMN id SET DEFAULT nextval('materia_id_seq'::REGCLASS);
登入後複製
登入後複製

伺服器內緩存

我們使用伺服器內緩存,因為:

  1. 從資料庫取得的資料永遠不會改變。
  2. 材質和融合端點使用相同的資料。

更新main.go:

COPY materia(name,materia_type,grade,display_materia_type,description) FROM
 '<path_to_csv_file>/materiadata.csv' DELIMITER ',' CSV HEADER;
登入後複製
登入後複製

更新 api/helpers.go:

? codebase
├─ cmd
│  └─ api
│     ├─ errors.go
│     ├─ handlers.go
│     ├─ helpers.go
│     ├─ main.go
│     ├─ middleware.go
│     └─ server.go
├─ internal
│  ├─ database --- db.go
│  ├─ env --- env.go
│  ├─ request --- json.go
│  ├─ response --- json.go
│  └─ validator
│     ├─ helpers.go
│     └─ validators.go
├─ go.mod
├─ LICENSE
├─ Makefile
├─ README.md
└─ README.html
登入後複製
登入後複製

api/handlers.go 中的融合處理程序

HTTP_PORT=4444
DB_DSN=go_client:<password>@localhost:5432/materiafusiondb?sslmode=disable
API_TIMEOUT_SECONDS=5
API_CALLS_ALLOWED_PER_SECOND=1
登入後複製
登入後複製

完整的處理程序程式碼可以在這裡找到。

Swagger UI 和 OpenAPI 定義文檔

新增 Swagger 庫:

go get github.com/joho/godotenv
登入後複製
登入後複製

在routes.go中取消註解Swagger行,並新增導入:

// At the beginning of main():
err := godotenv.Load(".env") // Loads environment variables from .env file
if err != nil { // This will be true in prod, but that's fine.
  fmt.Println("Error loading .env file")
}


// Modify config struct:
type config struct {
  baseURL string
  db      struct {
    dsn string
  }
  httpPort                 int
  apiTimeout               int
  apiCallsAllowedPerSecond float64
}

// Modify run() to use the new values from .env:
cfg.httpPort = env.GetInt("HTTP_PORT")
cfg.db.dsn = env.GetString("DB_DSN")
cfg.apiTimeout = env.GetInt("API_TIMEOUT_SECONDS")
cfg.apiCallsAllowedPerSecond = float64(env.GetInt("API_CALLS_ALLOWED_PER_SECOND"))

// cfg.baseURL = env.GetString("BASE_URL") - not required
登入後複製
登入後複製

在處理程序、DTO 和模型檔案中,新增 Swagger 文件的註解。請參閱此以了解所有選項。

在終端機中,運作:

go get github.com/didip/tollbooth
登入後複製
登入後複製

這將建立一個 api/docs 資料夾,其中包含可用於 Go、JSON 和 YAML 的定義。

要測試它,請啟動本機伺服器並開啟 http://localhost:4444/docs。


最終資料夾結構:

func (app *application) contentTypeCheck(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  if r.Header.Get("Content-Type") != "application/json" {
   app.unsupportedMediaType(w, r)

   return
  }
  next.ServeHTTP(w, r)
 })
}


func (app *application) rateLimiter(next http.Handler) http.Handler {
 limiter := tollbooth.NewLimiter(app.config.apiCallsAllowedPerSecond, nil)
 limiter.SetIPLookups([]string{"X-Real-IP", "X-Forwarded-For", "RemoteAddr"})

 return tollbooth.LimitHandler(limiter, next)
}


func (app *application) apiTimeout(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  timeoutDuration := time.Duration(app.config.apiTimeout) * time.Second

  ctx, cancel := context.WithTimeout(r.Context(), timeoutDuration)
  defer cancel()

  r = r.WithContext(ctx)

  done := make(chan struct{})

  go func() {
   next.ServeHTTP(w, r)
   close(done)
  }()

  select {
  case <-done:
   return
  case <-ctx.Done():
   app.gatewayTimeout(w, r)
   return
  }
 })
}
登入後複製
登入後複製

3. 在 CockroachDB 中設定遠端 PostgreSQL 實例

  1. 使用此處的步驟。
  2. 建立憑證後,在專案中建立 /certs/root.crt 並在其中新增憑證。我們稍後將在 Google Run 配置中引用此文件。
  3. 警告! 我們將此資料夾推送到遠端儲存庫。將 certs/ 資料夾新增至 .gitignore。如果您願意,我們在本地創建證書只是為了測試連接。
  4. 現在,當您前往 CockroachDB → 儀表板 → 左側選單 → 資料庫時,您應該可以看到您建立的資料庫。

遷移

從本機資料庫執行個體中,執行:

brew install postgresql@17
登入後複製
登入後複製
登入後複製
  1. 到 CockroachDB → 左側選單 → 遷移 → 新增架構 → 拖曳剛剛取得的 SQL 檔案。除表資料插入之外的所有步驟都將運行。它還會向您顯示已執行的步驟清單。
  2. 在撰寫本文時,CockroachDB 中的 PostgreSQL 實例不支援 IMPORT INTO 等語句。因此,我必須在本機 SQL 檔案中建立 270 行的 INSERT 語句(我們可以從剛剛獲得的 pg_dump 輸出得出)。
  3. 登入遠端實例,並執行SQL檔案。

登入遠端實例:

# create the DB
createdb materiafusiondb
# step into the DB to perform SQL commands
psql materiafusiondb
登入後複製
登入後複製
登入後複製

4. 部署 Google Cloud Run 實例

  1. 像這樣建立一個 Dockerfile。
  2. 前往 Google Cloud Run 並為 API 建立一個新專案。
  3. 建立服務→ 從儲存庫持續部署使用雲端建置進行設定儲存庫提供者 = Github → 選擇您的儲存庫→ 建置類型 = Dockerfile → 儲存。
  4. 驗證 = 允許未經授權的呼叫
  5. 大多數預設值應該就可以了。
  6. 向下捲動至貨櫃 → 貨櫃港口 = 4444。
  7. 選擇變數和秘密選項卡,然後加入與本地 .env 檔案相同的環境變數。

價值觀:

  1. HTTP_PORT = 4444
  2. DB_DSN = ?sslmode=verify-full&sslrootcert=/app/certs/root.crt
  3. API_TIMEOUT_SECONDS = 5
  4. API_CALLS_ALLOWED_PER_SECOND = 1

使用 Google Secret Manager 取得證書

最後一塊拼圖。

  1. 搜尋 Secret Manager → 建立 Secret → Name = ‘DB_CERT’ → 上傳 CockroachDB 的 .crt 憑證。
  2. 在 Cloud Run →(您的服務)→ 點選 編輯持續部署 → 向下捲動至設定 → 開啟編輯器。
  3. 將此新增為第一步:
-- create an SQL user to be used by the Go server
CREATE USER go_client WITH PASSWORD 'xxxxxxxx';

-- The Go server doesn't ever need to add data to the DB. 
-- So let's give it just read permission.
CREATE ROLE readonly_role;
GRANT USAGE ON SCHEMA public TO readonly_role;

-- This command gives SELECT access to all future created tables. 
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly_role;

-- If you want to be more strict and give access only to tables that already exist, use this:
-- GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_role;

GRANT readonly_role TO go_client;
登入後複製
登入後複製
登入後複製

這將使 Cloud Build 在建置開始之前在我們的專案中建立檔案 certs/root.crt,以便 Dockerfile 可以存取它,即使我們從未將其推送到我們的 Github 儲存庫。


就是這樣。嘗試推送提交並檢查建置是否觸發。 Cloud Run 儀表板將顯示您所託管的 Go 伺服器的 URL。


有關「為什麼你做了 X 而不是 Y?」的問題讀這個。

對於您想了解或討論的任何其他內容,請訪問此處,或在下面發表評論。

以上是使用 Go、PostgreSQL、Google Cloud 和 CockroachDB 建立 API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Debian OpenSSL有哪些漏洞 Debian OpenSSL有哪些漏洞 Apr 02, 2025 am 07:30 AM

OpenSSL,作為廣泛應用於安全通信的開源庫,提供了加密算法、密鑰和證書管理等功能。然而,其歷史版本中存在一些已知安全漏洞,其中一些危害極大。本文將重點介紹Debian系統中OpenSSL的常見漏洞及應對措施。 DebianOpenSSL已知漏洞:OpenSSL曾出現過多個嚴重漏洞,例如:心臟出血漏洞(CVE-2014-0160):該漏洞影響OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻擊者可利用此漏洞未經授權讀取服務器上的敏感信息,包括加密密鑰等。

Beego ORM中如何指定模型關聯的數據庫? Beego ORM中如何指定模型關聯的數據庫? Apr 02, 2025 pm 03:54 PM

在BeegoORM框架下,如何指定模型關聯的數據庫?許多Beego項目需要同時操作多個數據庫。當使用Beego...

從前端轉型後端開發,學習Java還是Golang更有前景? 從前端轉型後端開發,學習Java還是Golang更有前景? Apr 02, 2025 am 09:12 AM

後端學習路徑:從前端轉型到後端的探索之旅作為一名從前端開發轉型的後端初學者,你已經有了nodejs的基礎,...

在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

如何在Debian上配置MongoDB自動擴容 如何在Debian上配置MongoDB自動擴容 Apr 02, 2025 am 07:36 AM

本文介紹如何在Debian系統上配置MongoDB實現自動擴容,主要步驟包括MongoDB副本集的設置和磁盤空間監控。一、MongoDB安裝首先,確保已在Debian系統上安裝MongoDB。使用以下命令安裝:sudoaptupdatesudoaptinstall-ymongodb-org二、配置MongoDB副本集MongoDB副本集確保高可用性和數據冗餘,是實現自動擴容的基礎。啟動MongoDB服務:sudosystemctlstartmongodsudosys

See all articles