我是使用stackoverflow作为作者的新手,希望能正确询问。
当前,我正在开发几个独立的spring boot应用程序,以创建自己的微服务环境。目前,我实现了几个spring boot rest服务:一个 spring cloud netflix eureka服务器,一个 authenticationservice提供JWT身份验证和一个 spring boot mvc前端 。 该答案的相关组件更详细:
所有服务(除了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。
希望有人可以解决,我的问题不是重复的。 (我什么都没找到)
提前谢谢