You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LexikJWT在AWS生产环境生成Token过慢问题求助

AWS部署Symfony JWT API性能问题排查

我是Lexik/Symfony/Docker新手,首次在AWS部署一个生成JWT Token的简单API,技术栈为Symfony 6.4、Docker、Ubuntu LTS 22.04。本地环境中Token生成耗时仅333ms,运行正常;但在AWS环境下,Token生成耗时超2秒,即使在容器内部执行curl请求也是如此。

认证方式为基础认证,数据库中存储有一个用户。已尝试以下操作但问题仍未解决,期望生产环境Token生成耗时能控制在1秒以内:

  • 修改.env文件指定PostgreSQL版本
  • 更换用户提供者为内存用户(排查数据库问题)
  • 对比本地与AWS容器的Dockerfile
  • 检查环境配置文件

Security配置

security:
    enable_authenticator_manager: true
    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
    providers:
        #unip_ad_user_provider:
            #id: App\Security\ADUnip\ADUnipUserProvider
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern: ^/api/v1/login
            stateless: true
            json_login:
                check_path: /api/v1/login
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        unsecure:
            pattern: ^/api/v1/doc
            security: false

        api:
            pattern: ^/api
            stateless: true
            jwt: ~
        #main:
        #    lazy: true
        #    provider: users_in_memory

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/api/v1/login, roles: PUBLIC_ACCESS }
        - { path: ^/api/v1/dev-route, roles: PUBLIC_ACCESS }
        - { path: ^/api/v1/healthCheck, roles: PUBLIC_ACCESS }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

when@test:
    security:
        password_hashers:
            # By default, password hashers are resource intensive and take time. This is
            # important to generate secure password hashes. In tests however, secure hashes
            # are not important, waste resources and increase test times. The following
            # reduces the work factor to the lowest possible values.
            Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
                algorithm: auto
                cost: 4 # Lowest possible value for bcrypt
                time_cost: 3 # Lowest possible value for argon
                memory_cost: 10 # Lowest possible value for argon

Nelmio API Doc配置

nelmio_api_doc:
    documentation:
        servers:
            #- url : '%env(HTTP_SERVER_URL)%'
            #  description: API over HTTP
            - url:  '%env(HTTPS_SERVER_URL)%'
              description: API over HTTPS
        info:
            title: API OCCEA/KSL EDITIQUE
            description: API REST pour les flux OCCEA Editique
            version: '%env(API_VERSION)%'
        components:
            securitySchemes:
                Bearer:
                    type: http
                    scheme: bearer
                    bearerFormat: JWT
        security:
            - Bearer: []
        paths:
            /api/v1/login:
                post:
                    tags:
                        - Web Services Editique
                    summary: GET JWT TOKEN
                    description: Web service for generating token.
                    operationId: getToken
                    security: []
                    requestBody:
                        required: true
                        content:
                            application/json:
                                schema:
                                    type: object
                                    properties:
                                        username:
                                            type: string
                                        password:
                                            type: string
                    responses:
                        '200':
                            description: Token response
                            content:
                                application/json:
                                    schema:
                                        type: object
                                        properties:
                                            token:
                                                type: string
                                                description: Token JWT
                        '400':
                            description: Bad request
                            content:
                                application/json:
                                    schema:
                                        type: object
                                        properties:
                                            code:
                                                type: integer
                                                description: status code of response
                                            message:
                                                type: string
                                                description: detail about error
    areas: # to filter documented areas
        path_patterns:
            #- ^/api/v1/(?!/doc|doc.json$) # Accepts routes under /api except /api/doc
            - ^/api/v1/contractDocuments # Accepts routes under /api except /api/doc
            # ONLY FOR TESTING = RE7
            - ^/api/v1/xmlForKsl # Accepts routes under /api except /api/doc
            # healthCheck
            - ^/api/v1/healthCheck # Accepts routes under /api except /api/doc

Entrypoint.sh脚本

#!/bin/bash
# set -e
# Note: we don't just use "apache2ctl" here because it itself is just a shell-script wrapper around apache2 which provides extra functionality like "apache2ctl start" for launching apache2 in the background.
# (also, when run as "apache2ctl <apache args>", it does not use "exec", which leaves an undesirable resident shell process)

: "${APACHE_CONFDIR:=/etc/apache2}"
: "${APACHE_ENVVARS:=$APACHE_CONFDIR/envvars}"
if test -f "$APACHE_ENVVARS"; then
  . "$APACHE_ENVVARS"
fi
# Apache gets grumpy about PID files pre-existing
: "${APACHE_RUN_DIR:=/var/run/apache2}"
: "${APACHE_PID_FILE:=$APACHE_RUN_DIR/apache2.pid}"
rm -f "$APACHE_PID_FILE"

# create missing directories
# (especially APACHE_RUN_DIR, APACHE_LOCK_DIR, and APACHE_LOG_DIR)

for e in "${!APACHE_@}"; do
  if [[ "$e" == *_DIR ]] && [[ "${!e}" == /* ]]; then
    # handle "/var/lock" being a symlink to "/run/lock", but "/run/lock" not existing beforehand, so "/var/lock/something" fails to mkdir
    #   mkdir: cannot create directory '/var/lock': File exists
    dir="${!e}"
    while [ "$dir" != "$(dirname "$dir")" ]; do
      dir="$(dirname "$dir")"
      if [ -d "$dir" ]; then
        break
      fi
      absDir="$(readlink -f "$dir" 2>/dev/null || :)
      if [ -n "$absDir" ]; then
        mkdir -p "$absDir"
      fi
    done
    mkdir -p "${!e}"
  fi
done

echo "inside entrypoint.sh"

php --version

bin/console doctrine:database:create --no-interaction --if-not-exists --connection=default
bin/console doctrine:migrations:migrate --allow-no-migration --no-interaction
php bin/console cache:clear

chown -R www-data:www-data /var/www/var
exec apache2 -DFOREGROUND "$@"

内容的提问来源于stack exchange,提问作者Hba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 13:55:55