java - HTTP 错误 502.3 - 在 azure tomcat 应用程序服务中部署 Spring boot 应用程序后出现错误网关

标签 java azure tomcat spring-boot azure-web-app-service

我在azure tomcat应用程序服务中部署了spring boot Rest应用程序。在这里,我使用 FTP 将应用程序从本地 tomcat webapps 文件夹复制到 azure tomcat webapps fodler(复制的应用程序文件夹结构,而不是 war 文件)。

它工作正常..但一段时间后服务器没有响应并返回 HTTP 错误 502.3 - 错误网关。

此错误的原因可能是什么。我的spring配置有问题吗?感谢任何帮助。

我们有两种 URI,一种是健康检查 URI,另一种是从数据库获取数据。

当应用服务关闭时 - 只有 myapp/healthcheck 返回状态代码 200。

其余所有具有 uri - myapp/ssp/*** 返回状态代码 502.3 的请求

当我重新启动应用程序服务时,一切正常,但一段时间后问题再次出现。

我怀疑我的 AuthenticationFilter.java 和 RequestValidator 存在问题。 java 和 ControllerAdvice 文件

这是 Spring Boot 配置

这是我的配置。 `@SpringBootApplication( 排除 = HibernateJpaAutoConfiguration.class ) @ComponentScan( { "com.xx.ssp", "com.microsoft.applicationinsights"} ) 公共(public)类 SSPApplication{

/**
 * @param args
 */
public static void main( String[ ] args ) {

    SpringApplication sspSpringBootApplciation = new SpringApplication( SSPApplication.class );
    sspSpringBootApplciation.addListeners( new ApplicationPidFileWriter( ) );
    sspSpringBootApplciation.run( args );
}

/**
 * @return
 */
@Bean
public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter( ) {

    return new ApplicationSecurity( );
}

@Bean
public String telemetryConfig( ) {

    String telemetryKey = "zzzz";
    if( telemetryKey != null ){
        TelemetryConfiguration.getActive( ).setInstrumentationKey( telemetryKey );
    }
    return telemetryKey;
}

@Bean
public FilterRegistrationBean aiFilterRegistration( ) {

    FilterRegistrationBean registration = new FilterRegistrationBean( );
    registration.setFilter( webRequestTrackingFilter( ) );
    registration.addUrlPatterns( "/*" );
    registration.setOrder( 1 );
    return registration;
}

@Bean( name = "WebRequestTrackingFilter" )
public Filter webRequestTrackingFilter( ) {

    return new WebRequestTrackingFilter( );
}

@Bean
public ErrorPageFilter errorPageFilter( ) {

    return new ErrorPageFilter( );
}

@Bean
public FilterRegistrationBean disableSpringBootErrorFilter( ErrorPageFilter filter ) {

    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean( );
    filterRegistrationBean.setFilter( filter );
    filterRegistrationBean.setEnabled( false );
    return filterRegistrationBean;
}

} `

`@ControllerAdvice 公共(public)类 RestEntityExceptionHandler 扩展 ResponseEntityExceptionHandler{

@Autowired
private Environment environment;

private SSPLogger logger = new SSPLogger( getClass( ) );

/**
 * @return
 */
private String getEnvironment( ) {

    String[ ] activeProfiles = environment.getActiveProfiles( );
    if( activeProfiles != null && activeProfiles.length > 1 ){
        return SSPEnvironment.getEnvironment( activeProfiles[ 0 ] ).name( );
    }
    return SSPEnvironment.UNKNOWN.name( );

}

/**
 * @param errorCode
 * @return
 */
private HttpStatus getHttpstatusCode( String errorCode ) {

    try{
        return HttpStatus.valueOf( Integer.parseInt( errorCode ) );
    } catch ( Exception e ){

        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
}

/**
 * @param ex
 * @return
 */
@ExceptionHandler( {    .class , IllegalStateException.class , SSPRestException.class ,
        Exception.class } )
@ResponseBody
ResponseEntity< Object > handleControllerException( Exception ex ) {

    HttpHeaders headers = new HttpHeaders( );
    headers.setContentType( MediaType.APPLICATION_JSON );
    ex.printStackTrace( );
    if( ex instanceof SSPRestException ){
        SSPRestException exp = ( SSPRestException ) ex;
        CustomErrorResponse customErrorResponse = new CustomErrorResponse( );
        customErrorResponse.setStatusCode( exp.getErrorCode( ) );
        customErrorResponse.setErrorMessage( exp.getErrorMessage( ) );
        customErrorResponse.setErrorDescription( exp.getErrorDescription( ) );
        customErrorResponse.setErrorKey( exp.getErrorKey( ) );
        customErrorResponse.setEnvironment( getEnvironment( ) );
        logger.logException( LogLevel.ERROR , customErrorResponse );

        HttpStatus httpstatusCode = getHttpstatusCode( exp.getErrorCode( ) );

        return new ResponseEntity<>( customErrorResponse , headers , httpstatusCode );
    }
    if( ex instanceof HttpRequestMethodNotSupportedException ){
        String statusCode = "405";
        headers.setContentType( MediaType.APPLICATION_JSON );
        CustomErrorResponse customErrorResponse = new CustomErrorResponse( );
        customErrorResponse.setStatusCode( statusCode );
        customErrorResponse.setErrorMessage( ex.getMessage( ) );
        customErrorResponse.setErrorKey( "" );
        customErrorResponse.setEnvironment( getEnvironment( ) );
        HttpStatus httpstatusCode = getHttpstatusCode( statusCode );
        return new ResponseEntity<>( customErrorResponse , headers , httpstatusCode );
    } else{
        String statusCode = "UNKNOWN";
        CustomErrorResponse customErrorResponse = new CustomErrorResponse( );
        customErrorResponse.setStatusCode( statusCode );
        customErrorResponse.setErrorMessage( ex.getMessage( ) );
        if( ex.getCause( ) != null ){
            customErrorResponse.setErrorDescription( ex.getCause( ).getMessage( ) );
        }
        customErrorResponse.setErrorKey( "UNAHNDLED_EXCEPTION" );
        customErrorResponse.setEnvironment( getEnvironment( ) );
        HttpStatus httpstatusCode = getHttpstatusCode( statusCode );
        logger.logException( LogLevel.ERROR , customErrorResponse );
        return new ResponseEntity<>( customErrorResponse , headers , httpstatusCode );
    }
}

}` ```` @Order( SecurityProperties.ACCESS_OVERRIDE_ORDER ) 公共(public)类 ApplicationSecurity 扩展了 WebSecurityConfigurerAdapter{

    @Override
    protected void configure( HttpSecurity http ) throws Exception {

    http.csrf( ).disable( ).sessionManagement( ).sessionCreationPolicy( SessionCreationPolicy.STATELESS );
    http.authorizeRequests( ).antMatchers( "/spp/**" ).addFilterBefore( new AuthenticationFilter( ) , SecurityContextPersistenceFilter.class );
http.authorizeRequests( ).antMatchers( "/healthcheck/**" , "/unoauth/**" ).permitAll( ).antMatchers( HttpMethod.OPTIONS , "/**" ).permitAll( );

```

`@组件 公共(public)类 RequestValidator 扩展了 HandlerInterceptorAdapter{

@Autowired
private AppConstants appConstants;

@Autowired
private CacheTemplate cacheTemplate;

@Autowired
private RestClient restClient;

/*
 * (non-Javadoc)
 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#
 * afterCompletion(javax.servlet.http.HttpServletRequest,
 * javax.servlet.http.HttpServletResponse, java.lang.Object,
 * java.lang.Exception)
 */
@Override
public void afterCompletion( HttpServletRequest request , HttpServletResponse response , Object object ,
                Exception arg3 ) throws Exception {

}

/**
 * @param cookies
 * @return
 */
private String getGsidFromRequest( Cookie[ ] cookies ) {

    String gsid = null;
    if( cookies != null ){
        Cookie gsidCookie = Arrays.stream( cookies ).filter( x-> x.getName( ).equals( "gsid" ) ).findFirst( )
                        .orElse( null );
        if( gsidCookie != null ){
            gsid = gsidCookie.getValue( );
        }
        if( Utils.isEmpty( gsid ) ){
            throw new SSPRestException( ErrorCode.InvalidRequest , "gsid is missing" , getClass( ) );
        }
    }
    return gsid;
}

/**
 * @return
 */
private UserCashedInfo getTempUserInfo( ) {

    UserCashedInfo cashedInfo = new UserCashedInfo( );
    cashedInfo.setEmailId( "sssssss" );
    cashedInfo.setUserId( 1 );
    cashedInfo.setUserRole( 1 );
    cashedInfo.setRefreshToken( "" );
    cashedInfo.setCaseInstanceId( 1 );
    cashedInfo.setUserName( "Test User" );
    return cashedInfo;
}

/**
 * @param accessToken
 * @return
 */
private boolean isRequestHadAccessToken( String accessToken ) {

    if( Utils.isEmpty( accessToken ) ){
        throw new SSPRestException( ErrorCode.InvalidRequest , "Access Token is Mandatory" , getClass( ) );
    }
    return true;
}

/*
 * (non-Javadoc)
 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#
 * postHandle(javax.servlet.http.HttpServletRequest,
 * javax.servlet.http.HttpServletResponse, java.lang.Object,
 * org.springframework.web.servlet.ModelAndView)
 */
@Override
public void postHandle( HttpServletRequest request , HttpServletResponse response , Object object ,
                ModelAndView model ) throws Exception {

}

/*
 * (non-Javadoc)
 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#
 * preHandle(javax.servlet.http.HttpServletRequest,
 * javax.servlet.http.HttpServletResponse, java.lang.Object)
 */
@Override
public boolean preHandle( HttpServletRequest request , HttpServletResponse response , Object object )
                throws Exception {

    boolean isValidRequest = false;

    String isOauthRequiredParam = request.getParameter( "isOauth" );

    String methodName = request.getMethod( );
    if( methodName != null && methodName.equalsIgnoreCase( "OPTIONS" ) ){
        isValidRequest = true;
    }

    if( !isValidRequest ){
        if( !Utils.isEmpty( isOauthRequiredParam ) && isOauthRequiredParam.equals( "false" ) ){
            isValidRequest = true;
            UserCashedInfo cashedInfo = getTempUserInfo( );
            Utils.updateUserLocalThread( cashedInfo );
        } else{
            String accessToken = request.getHeader( "oauth" );
            boolean isRequestHadAccessToken = isRequestHadAccessToken( accessToken );
            String gsid = getGsidFromRequest( request.getCookies( ) );
            if( isRequestHadAccessToken && !Utils.isEmpty( gsid ) ){
                UserCashedInfo cashedInfo = cacheTemplate.getItem( gsid );
                if( cashedInfo != null ){
                    String userEmail = validateAccessToken( accessToken );
                    if( userEmail != null && userEmail.equals( cashedInfo.getEmailId( ) ) ){
                        Utils.updateUserLocalThread( cashedInfo );
                        isValidRequest = true;
                    } else{
                        throw new SSPRestException( ErrorCode.UnAuthenticateUser , "" , getClass( ) );
                    }

                } else{
                    throw new SSPRestException( ErrorCode.UnAuthenticateUser , "" , getClass( ) );
                }
            } else{
                throw new SSPRestException( ErrorCode.GsidMissing , "" , getClass( ) );
            }
        }
    }
    return isValidRequest;
}

/**
 * @param accessToken
 * @return
 */
private String validateAccessToken( String accessToken ) {

    CustomeJsonResponse validateResponse = restClient.ValidateAcessToken( accessToken );
    if( validateResponse.getStatusCode( ) == 200 ){
        return ( ( ValidateAcessTokenResponse ) validateResponse.getData( ) ).getAccess_token( )
                        .get( appConstants.getUserEmail( ) );
    } else{
        throw new SSPRestException( ErrorCode.ApValidateAccessTokenError , "" , getClass( ) );
    }
}

} `

` 公共(public)类 AuthenticationFilter 扩展 GenericFilter{

private SSPLogger logger = new SSPLogger( getClass( ) );

@Override
public void destroy( ) {

}

/*
 * (non-Javadoc)
 * @see com.xxx.ssp.security.GenericFilter#doFilter(javax.servlet.
 * ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
 */
@Override
public void doFilter( ServletRequest req , ServletResponse res , FilterChain chain )
                throws IOException , ServletException {

    HttpServletRequest request = ( HttpServletRequest ) req;

    String accessToken = request.getHeader( "oauth" );
    boolean isValidRequest = false;
    String isOauthRequiredParam = request.getParameter( "isOauth" );
    String methodName = request.getMethod( );
    if( methodName != null && methodName.equalsIgnoreCase( "OPTIONS" ) ){
        isValidRequest = true;
    } else{
        if( !Utils.isEmpty( isOauthRequiredParam ) && isOauthRequiredParam.equals( "false" ) ){
            isValidRequest = true;
        } else{
            logger.debug( "Requeste validation required : true" );

            boolean isRequestHadAccessToken = isRequestHadAccessToken( accessToken );
            String gsid = getGsidFromRequest( request.getCookies( ) );

            if( isRequestHadAccessToken && !Utils.isEmpty( gsid ) ){
                isValidRequest = true;
            } else{
                throw new SSPRestException( ErrorCode.InternalServerError ,
                                " Access Token or GSID is mssing in the request" , getClass( ) );
            }
        }
    }
    if( isValidRequest ){
        chain.doFilter( req , res );
    } else{
        throw new SSPRestException( ErrorCode.UnauthorisedRequest , "Invalid User" , getClass( ) );
    }
}

/**
 * @param cookies
 * @return
 */
private String getGsidFromRequest( Cookie[ ] cookies ) {

    String gsid = null;
    if( cookies != null ){
        Cookie gsidCookie = Arrays.stream( cookies ).filter( x-> x.getName( ).equals( "gsid" ) ).findFirst( )
                        .orElse( null );
        if( gsidCookie != null ){
            gsid = gsidCookie.getValue( );
        }
        if( Utils.isEmpty( gsid ) ){
            throw new SSPRestException( ErrorCode.UnAuthenticateUser , "gsid is missing" , getClass( ) );
        }
    }
    return gsid;
}

/*
 * (non-Javadoc)
 * @see
 * com.xxx.ssp.security.GenericFilter#init(javax.servlet.FilterConfig)
 */
@Override
public void init( FilterConfig arg0 ) throws ServletException {

}

/**
 * @param accessToken
 * @return
 */
private boolean isRequestHadAccessToken( String accessToken ) {

    if( Utils.isEmpty( accessToken ) ){
        throw new SSPRestException( ErrorCode.UnAuthenticateUser , "Access Token is Mandatory" , getClass( ) );
    }
    return true;
}

}`

`@组件 公共(public)类 SSPCORSFilter 实现 Filter{

private SSPLogger sSPLogger = null;

public SSPCORSFilter( ){

    sSPLogger = new SSPLogger( getClass( ) );
    sSPLogger.info( "CORSFilter initialized" );
}

@Override
public void destroy( ) {

}

@Override
public void doFilter( ServletRequest req , ServletResponse res , FilterChain chain )
                throws IOException , ServletException {

    String origin = ( ( HttpServletRequest ) req ).getHeader( "Origin" );
    sSPLogger.info( "CORSFilter Request origin : " + origin );
    HttpServletResponse response = ( HttpServletResponse ) res;
    response.setHeader( "Access-Control-Allow-Origin" , origin );
    response.setHeader( "Access-Control-Allow-Credentials" , "true" );
    response.setHeader( "Access-Control-Allow-Methods" , "GET, POST, PUT, DELETE, OPTIONS" );
    // response.setHeader( "Access-Control-Allow-Headers" , "Content-Type,
    // Accept, X-Requested-With, oauth" );
    response.setHeader( "Access-Control-Request-Headers" ,
                    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, oauth, access-control-allow-credentials" );
    response.setHeader( "Access-Control-Allow-Headers" ,
                    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, oauth, access-control-allow-credentials" );

    chain.doFilter( req , res );
}

@Override
public void init( FilterConfig filterConfig ) {

}

}`

最佳答案

我在查看线程转储后解决了这个问题。根本原因是数据库连接池发生死锁。所以我的请求没有获得数据库连接..超时后,IIS 服务器返回我的请求,状态为“http-error-502-3-bad-gateway”

关于java - HTTP 错误 502.3 - 在 azure tomcat 应用程序服务中部署 Spring boot 应用程序后出现错误网关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46982311/

相关文章:

c# - 使用 Auth0 进行 Azure AD 身份验证

java - 将请求传递给正确的应用程序

git - 如何防止在 tomcat 的 context.xml 中存储 postgres 密码

java - 未找到 Retrofit 注释。 (参数#2)

java - 带有 GUI 的程序控制 Java Web 浏览器

java - 获取 java.lang.ClassNotFoundException :MalformedPatternException

css - 在 azure Node js Web 应用程序上找不到字体 .woff 404

javascript - Angular或Three.js不是从服务器提取图像,而是从浏览器缓存中提取图像

tomcat - 无法远程启动 Apache Tomcat 服务器 (linux)

java - 安卓 : Displaying information in two columns instead of one for BaseAdapter