春季启动:Eureka客户端请求非常慢

时间:2020-05-30 19:08:02

标签: java spring-boot spring-mvc netflix-eureka spring-cloud-netflix

我是使用stackoverflow作为作者的新手,希望能正确询问。

当前,我正在开发几个独立的spring boot应用程序,以创建自己的微服务环境。目前,我实现了几个spring boot rest服务:一个 spring cloud netflix eureka服务器,一个 authenticationservice提供JWT身份验证和一个 spring boot mvc前端 。 该答案的相关组件更详细:

  1. Spring boot authentication rest service =>提供JWT进行身份验证,注册为eureka客户端
  2. Spring boot mvc前端=>提供注册为eureka客户端的JSP前端
  3. Spring cloud netflix eureka服务器=>服务注册表以处理服务命名(spring.application.name),服务的负载平衡

所有服务(除了eureka服务器)都是eureka客户端,并且已在eureka服务器上正确注册。 尤里卡服务器对我来说很重要,因为它具有负载平衡和处理服务命名功能。

现在我的问题是: 我目前面临的问题是,当我使用在eureka服务器中注册的服务名称(例如http://authenticationservice/authenticate)请求身份验证服务时,需要花费超过11秒钟的时间才能做出响应。我尝试使用直接ip地址和端口,响应以毫秒为单位。 (例如http://127.0.0.1:8081/authenticate) 我找不到性能问题的来源。我的服务中没有实现任何粗俗的魔术。

eureka服务器 pom.xml(部分):

...
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <build>
        <finalName>discoveryservice</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>de.prototype.server.service.discovery.DiscoveryserviceApp</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

eureka服务器 主类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryserviceApp
{
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryserviceApp.class, args);
    }
}

eureka服务器 application.properties

# Give a name to the eureka server
spring.application.name=eureka-server

# default port for eureka server
server.port=8761

eureka.client.register-with-eureka=false

身份验证服务 pom.xml(部分):

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.4.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>de.prototype.server.service</groupId>
            <artifactId>prototype-server-service-security</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>authenticationservice</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>de.prototype.server.service.authentication.AuthenticationserviceApp</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

身份验证服务主要类别:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;

import de.prototype.server.service.common.ServiceConstant;

@SpringBootApplication
@EnableEurekaClient
@EntityScan(basePackages = {ServiceConstant.ENTITY_SCAN})
@ComponentScan(basePackages = {ServiceConstant.COMPONENT_SCAN})
public class AuthenticationserviceApp
{
    public static void main(String[] args)
    {
        SpringApplication.run(AuthenticationserviceApp.class, args);
    }
}

身份验证服务休息控制器:

import java.util.Arrays;
import java.util.HashSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import de.prototype.server.service.common.dto.Token;
import de.prototype.server.service.security.jwt.Request;
import de.prototype.server.service.security.jwt.util.TokenUtil;
import de.prototype.server.service.security.jwt.validation.UserDetailsService;
import de.server.service.authentication.api.AuthenticationserviceMappingConstant;

@RestController
@CrossOrigin
public class AuthenticationserviceController
{
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @PostMapping(value = AuthenticationserviceMappingConstant.AUTHENTICATE_PATH,
                 produces = "application/json; charset=utf-8")
    public Token authenticate(@RequestBody Request authenticationRequest) throws Exception
    {
        authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());

        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());

        // get roles for user ...

        return new Token(tokenUtil.generateToken(userDetails, new HashSet<>(Arrays.asList("ROLE_ADMIN", "ROLE_USER"))));
    }

    private void authenticate(String username,
                              String password) throws Exception
    {
        try
        {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        }
        catch(DisabledException e)
        {
            throw new Exception("USER_DISABLED", e);
        }
        catch(BadCredentialsException e)
        {
            throw new Exception("INVALID_CREDENTIALS", e);
        }
    }
}

身份验证服务 application.properties:

server.port=8081

spring.application.name=authenticationservice
eureka.client.service-url.default-zone=http://localhost:8761/eureka

jwt.secret=2secret2publish

客户端请求,以从authenticationservice检索令牌 template变量是org.springframework.web.client.RestTemplate

ResponseEntity<Token> result = (ResponseEntity<Token>)template.exchange("http://authenticationservice/authenticate"),
                                                                        HttpMethod.POST,
                                                                        object != null ? new HttpEntity<>(object, createDefaultHttpHeaders(token))
                                                                                       : new HttpEntity<>(createDefaultHttpHeaders(token)),
                                                                        resultType);
        if(!resultType.isInstance(result.getBody()))
        {
            throw new ServiceRequestException("The result type of the request does not match the expected type.");
        }
        return (T)result.getBody();

    // private method used in requesting service code
    // it is a common method, the token variable is always null on requesting authenticationservice!
    private HttpHeaders createDefaultHttpHeaders(final String token)
    {
        HttpHeaders headers = new HttpHeaders();
        headers.set(ServiceConstant.HTTP_HEADER_CONTENT_TYPE, "application/json");
        if(token != null)
        {
            headers.set("Authorization", token);
        }
        return headers;
    }

所有请求通常都可以使用,但是以eureka命名的请求要花很长时间,而不是直接使用ip和port。

希望有人可以解决,我的问题不是重复的。 (我什么都没找到)

提前谢谢

0 个答案:

没有答案