Реализация микросервисного API-шлюза на базе Openresty+Lua
Реализация микросервисного API-шлюза на базе Openresty+Lua
Что такое микросервисный API-шлюз

Шлюз микросервисов — это ключевой компонент архитектуры микросервисов. Он служит точкой входа для получения клиентских запросов и их маршрутизации в соответствующие микросервисы. Он действует как «портал» между внешними и внутренними микросервисами, координируя поток запросов и доступ к сервисам всей системы микросервисов. Функции следующие:

  1. Маршрутизация: микросервисышлюз направляет запрос соответствующему экземпляру микросервиса на основе запрошенного пути и других условий. Он может перенаправлять запросы соответствующим микросервисам на основе различных шаблонов и правил URL-адресов.,Тем самым скрываются фактический адрес и структура серверных микросервисов.
  2. Балансировка нагрузки: микросервисный шлюз может равномерно распределять запросы по нескольким экземплярам серверных микросервисов.,Для обеспечения балансировки нагрузки каждого экземпляра,Повысьте доступность и производительность системы.
  3. Аутентификация и проверка подлинности: микросервисышлюз может справиться с задачей аутентификации и аутентификации пользователей, гарантируя, что только авторизованные пользователи смогут получить доступ к определенному микросервису. Это помогает защитить серверные службы от несанкционированного доступа.
  4. Безопасность: микросервисы шлюз могут реализовать некоторые меры безопасности.,Например, брандмауэр, предотвращение атак и т. д.,Защитите серверные микросервисы от вредоносных атак.
  5. Кэш: шлюз может кэшировать некоторые часто запрашиваемые данные.,Тем самым снижая нагрузку на серверные микросервисы.,Улучшите скорость отклика системы.
  6. Ведение журнала и мониторинг: микросервисышлюз может записывать журналы запросов и ответов.,и предоставить показатели мониторинга,Помогите команде разработчиков диагностировать и решать проблемы.

Шлюз микросервисов упрощает процесс взаимодействия между клиентом и серверными микросервисами, сокращает объем логики, которую необходимо обрабатывать клиенту, и предоставляет уровень промежуточного программного обеспечения, которое может лучше управлять и обслуживать всю систему микросервисов. Распространенные шлюзы микросервисов включают Nginx, Spring Cloud Gateway, Kong, INgress, Istio и т. д.

Зачем изобретать велосипед?

Именно потому, что шлюз микросервисного API настолько важен, он всегда был предметом споров среди военных стратегов. Традиционные ИТ-гиганты уже давно работают в этой области. Согласно отчету о жизненном цикле API, опубликованному Gartner в 2018 году, Google, CA, IBM, Red Hat и Salesforce являются ведущими поставщиками, а Kong, который более знаком разработчикам, находится в ряду провидцев.

Итак, вопрос в том, зачем нам строить новое колесо? Проще говоря, это потому, что нынешних шлюзов API микросервисов недостаточно для удовлетворения наших потребностей. Давайте сначала посмотрим на коммерческие продукты с закрытым исходным кодом. Их функции очень полны и охватывают управление полным жизненным циклом, такое как разработка API, многоязычный SDK, документация, тестирование и выпуск, а также предоставление услуг SaaS. Некоторые из них даже интегрируются с общедоступными облаками. и очень удобен в использовании. Но в то же время они приносят и две болевые точки.

  • Проблема с блокировкой платформы. API шлюз - это вход в деловой трафик. Он не похож на картинки, видео и т.п. CDN Ускоренный небизнес-трафик можно перенести по желанию, API Большая часть бизнес-логики будет связана с шлюзом. Если вы используете решение с закрытым исходным кодом, вам будет сложно плавно и экономически эффективно перейти на другие платформы.
  • Проблема, которую невозможно развить снова. Как правило, крупные и средние предприятия имеют свои уникальные потребности и требуют индивидуальной разработки, но в настоящее время вы можете полагаться только на производителей и не можете заниматься вторичной разработкой самостоятельно.

Это одна из причин, почему решения шлюзов API с открытым исходным кодом стали популярными. Однако существующие продукты с открытым исходным кодом не всесильны и имеют множество недостатков.

  • полагаться PostgreSQL、MySQL и другие реляционные базы данных. Таким образом, при изменении конфигурации узел шлюза может только опрашивать базу данных. Это не только приводит к медленному вступлению в силу конфигурации, но и усложняет код, затрудняя его понимание, в то же время база данных также становится единой точкой и узким местом в производительности системы, что делает невозможным гарантировать; общая высокая доступность. если ты положишь API шлюз используется для Kubernetes В этой среде реляционные базы данных будут выглядеть более громоздкими и не способствующими быстрому масштабированию.
  • Плагины не могут быть загружены в горячем режиме. Когда вы добавляете новый плагин или изменяете код существующего плагина, вам необходимо перезагрузить сервис, чтобы он вступил в силу. Это то же самое, что и необходимость перезагрузки после изменения конфигурации Nginx, что, очевидно, повлияет на запросы пользователей.
  • Структура кода сложна, Трудно освоить. В некоторых проектах с открытым исходным кодом реализована многоуровневая объектно-ориентированная инкапсуляция, и некоторая простая логика стала запутанной. Но на самом деле для API шлюз Такая сцена,Прямое выражение будет более ясным и эффективным.,Это также более способствует вторичному развитию.
  • Поэтому нам нужен более легкий, облачный и удобный для разработки API шлюз

Что такое опенрести

OpenResty (открытая сетевая архитектура) — это сервер веб-приложений с открытым исходным кодом, основанный на Nginx и LuaJIT. Он сочетает в себе мощные функции языка сценариев Nginx и Lua, предоставляя разработчикам высокопроизводительный, масштабируемый и гибкий способ создания веб-приложений и микросервисов. OpenResty использует Nginx в качестве сервера и прокси, расширяя функциональность Nginx за счет внедрения механизма сценариев Lua (LuaJIT). Lua — это легкий язык сценариев с кратким синтаксисом и мощной расширяемостью, позволяющий OpenResty реализовывать более сложную логику и настраиваемые функции без изменения исходного кода Nginx. Основные особенности и преимущества:

  1. Высокая производительность: OpenResty использует асинхронную, неблокирующую, управляемую событиями архитектуру Nginx в сочетании с высокой производительностью LuaJIT для обработки большого количества одновременных запросов и подходит для сценариев с высоким трафиком и высокими требованиями к производительности.
  2. Масштабируемость: с помощью сценариев Lua разработчики могут легко расширять и настраивать функции OpenResty для удовлетворения конкретных потребностей без изменения основного кода Nginx.
  3. Легкость: OpenResty сам по себе требует меньше ресурсов и относительно прост в установке и развертывании.
  4. Гибкость: OpenResty может выступать в качестве веб-сервера.、обратный прокси、балансировщик нагрузки、APIшлюзи другие роли,Подходит для различных типов сценариев применения.
  5. Поддержка сообщества: OpenResty имеет активное сообщество и предоставляет множество плагинов и модулей, облегчающих использование и расширение разработчиков.

OpenResty обычно используется для создания высокопроизводительных веб-приложений, сервисов API и шлюзов микросервисов. Он может заменить традиционные веб-серверы, обеспечивая при этом большую гибкость и возможности настройки. В крупномасштабных приложениях и средах с высоким уровнем параллелизма OpenResty продемонстрировал свои сильные преимущества и широко используется в интернет-компаниях, онлайн-играх, потоковом видео и других областях.

Введение передового опыта

Теперь мы используем Openresty+Lua для реализации микросервисного API-шлюза с функциями анализа токенов и аутентификации (разбор токенов и аутентификация реализованы в Openresty, и если токен недействителен, он напрямую отклоняется). Пусть все познакомятся с процессом разработки Openresty+Lua. Блок-схема выглядит следующим образом:

Описание процесса:

  • Пользователь вводит учетную запись и пароль для отправки запроса. После того, как Openresty получает запрос, он определяет, что это интерфейс входа в систему. Нет необходимости проверять аутентификацию и напрямую пересылать запрос в службу авторизации.
  • Служба авторизации получает пароль учетной записи пользователя и проводит проверку. После успешной аутентификации токен возвращается пользователю.
  • После того, как пользователь получает токен, он переносит его для доступа к другим запросам. После того, как openresty получает запрос, он определяет, требует ли интерфейс проверки подлинности.
  • openresty выполняет проверку и анализ токенов,Если проверка не удалась,Затем верните 401 пользователю,Если проверка прошла успешно,Затем перенаправьте ответный запрос в микросервисы.

Развертывание примера службы

Язык кода:javascript
копировать
package main

import (
 "fmt"
 jwt "github.com/dgrijalva/jwt-go"
 "github.com/gin-gonic/gin"
 "net/http"
 "time"
)

const secretKey = "Dav7kfq3iA8S!JUj8&CUkdnQe72E@Cw6" // Replace this with a strong secret key

// User struct represents a user.
type User struct {
 ID       int    `json:"id"`
 Username string `json:"username"`
 Password string `json:"password"`
}

var users = []User{
 {1, "kubesre", "123456"},
}

func GenerateToken(user User) (string, error) {
 token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
  "id":       user.ID,
  "username": user.Username,
  "exp":      time.Now().Add(time.Hour * 2).Unix(), // Token expires in 2 hours
 })

 return token.SignedString([]byte(secretKey))
}

func LoginHandler(c *gin.Context) {
 var input struct {
  Username string `json:"username"`
  Password string `json:"password"`
 }
 if err := c.ShouldBindJSON(&input); err != nil {
  c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
  return
 }

 for _, user := range users {
  if user.Username == input.Username && user.Password == input.Password {
   token, err := GenerateToken(user)
   if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
    return
   }

   c.JSON(http.StatusOK, gin.H{"token": token})
   return
  }
 }

 c.JSON(http.StatusUnauthorized, gin.H{"error": «Не удалось войти, пожалуйста, подтвердите свою учетную запись и пароль»})
}

func UserInfo(c *gin.Context) {
 c.JSON(http.StatusOK, gin.H{"message": "Круг эксплуатации и обслуживания облачных технологий!"})
}

func main() {
 r := gin.Default()

 // Route to handle user login
 r.POST("/login", LoginHandler)

 // Routes protected by JWT authentication middleware
 // You need to include the JWT token in the "Authorization" header for these routes
 r.GET("/user/info", UserInfo)

 fmt.Println("Server started at http://localhost:8080")
 r.Run(":8080")
}

Запустить сервис

Язык кода:javascript
копировать
$ go mod tidy
$ go run main.go

Развертывание Openresty

Язык кода:javascript
копировать
# Установите набор инструментов управления репозиторием:
$ yum install yum-utils

# Добавить адрес склада:
$ yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

# Установите рести:
$ yum install openresty-resty

# Установите ОПМ:
$ yum install openresty-opm

# Установите компонент Jwt:
$opm get SkyLothar/lua-resty-jwt

На этом этапе lua-resty-jwt установлен и его можно использовать напрямую.

НастроитьOpenresty

Плагин Auth-JWT:

Язык кода:javascript
копировать
$ cat /usr/local/openresty/lualib/resty/jwt.lua;
local auth_token = ngx.var.http_token
--Внедрение библиотеки json
local secret= "Dav7kfq3iA8S!JUj8&CUkdnQe72E@Cw6"
local cjson = require "cjson"
local jwt = require("resty.jwt")

--ngx.say(auth_token)
if auth_token == nil then
   local response = {}
   response["code"]=401
   ответ["сообщение"]="Пароль не существует"
   ngx.say(cjson.encode(response))
   ngx.exit(response.code)
else
  local jwt_obj = jwt:verify(secret, auth_token)
  if jwt_obj.verified == false then
        local response = {}
        response["code"]=401
        ответ["message"]="Токен недействителен"
        ngx.say(cjson.encode(response))
        ngx.exit(response.code)
   else
     ngx.exec('@user')
   end
end

НастроитьOpenresty:

Язык кода:javascript
копировать
$ cat /usr/local/openresty/nginx/conf/nginx.conf
...
# Требуется аутентификация
location /user/info {
              # Представляем расширение jwt.lua
              content_by_lua_file /usr/local/openresty/lualib/resty/jwt.lua;
        }

# Нет Требуется аутентификация
location /login {
   proxy_pass http://192.168.40.125:8080;
}

location @user {
  proxy_pass http://192.168.40.125:8080;
}
...

Перезагрузка Openresty вступает в силу:

Язык кода:javascript
копировать
$ /usr/local/openresty/bin/openresty -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
$  /usr/local/openresty/bin/openresty -s reload

проверять

Пользователь успешно входит в систему, и токен возвращается (выведите пароль учетной записи для входа и верните токен):

Если токен не передан, запросите 192.168.1.102/user/info (он вернет, что пароль не существует):

Если передан неправильный токен, запросите 192.168.1.102/user/info (будет возвращен неверный пароль):

Передайте правильный токен и запросите 192.168.1.102/user/info (обычный возвращаемый контент)

Подвести итог

В этой статье рассказывается о API шлюза микросервиса и о том, почему нам нужно изобретать велосипед. Он также реализует небольшой пример функции синтаксического анализа и аутентификации JWT через openresty+lua, а также дает определенное представление о функции расширения openresty. Следите за практическими примерами корпоративного уровня!

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода