HTTP错误502.3 - 在azure tomcat app service

时间:2017-10-27 19:38:56

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

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

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

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

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

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

保留所有拥有uri的请求 - myapp / ssp / ***返回状态码502.3

当我重新启动应用服务时,每件事情都有效,但经过一段时间后又重新发布。

我怀疑我的AuthenticationFilter.java&amp ;; RequestValidator。 java& ControllerAdvice文件

这是弹簧启动配置

这是我的配置。 `@SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class) @ComponentScan({" com.xx.ssp"," com.microsoft.applicationinsights"}) 公共类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 公共类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)     公共类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( );

```

`@Component 公共类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( ) );
    }
}

} `

` 公共类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;
}

}`

`@Component 公共类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 ) {

}

}`

1 个答案:

答案 0 :(得分:1)

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