服务发现

时间:2016-12-19 20:04:51

标签: java spring spring-boot netflix-eureka service-discovery

我有两个微服务,

  1. eureka-client-1在localhost上运行:8081
  2. eureka-client-2在localhost上运行:8082
  3. 这些都是在&eureka-server'注册的DiscoveryClients。在localhost上运行:8761。

    在下面的代码段中,我尝试从eureka-client-1调用eureka-client-2。我想调用http://localhost:8082而不是调用http://eureka-client-2,但这会在Eureka服务发现期间抛出java.net.UnknownHostException。

    搜索后,我发现我需要使用" Brixton"完成它。

    有没有办法用Camden.SR3做到这一点?

    请建议。

    @Component
    public class HystrixDemoService {   
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
        @HystrixCommand(fallbackMethod = "getFallbackCustomerName")
        public String getCustomerName() {
            RestTemplate restTemplate = new RestTemplate();
            URI uri = URI.create("http://eureka-client-2");     // fails here
            return restTemplate.getForObject(uri, String.class);
        }
    
        public String getFallbackCustomerName() {
            System.out.println("coming inside fallback method");
            return "Resillient Customer";
        }
    }
    

    的pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.example</groupId>
        <artifactId>demo-pranay-eureka-client1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>demo-pranay-eureka-client1</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.2.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Camden.SR3</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    

    客户端1的application.properties,类似于客户端2(只需更改名称,即eureka-client-2)

    spring.application.name=eureka-client-1
    server.port=8081
    eureka:
      client:
        registerWithEureka: true
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        leaseRenewalIntervalInSeconds: 10
        statusPageUrlPath: /info
        healthCheckUrlPath: /health
    

    eureka服务器的application.properties

    spring.application.name=eureka-service
    server.port=8761
    eureka:
      client:
        registerWithEureka: false
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        leaseRenewalIntervalInSeconds: 10
        statusPageUrlPath: /info
        healthCheckUrlPath: /health
    

4 个答案:

答案 0 :(得分:2)

对我来说,解决问题唯一需要做的就是将弹簧注释@LoadBalanced添加到

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

答案 1 :(得分:2)

解决方案是您错过了@LoadBalanced
如果您使用Spring Boot或Sprint Cloud,则我更喜欢使用RestTemplateBuilder builder

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
  }

如果仅使用spring,建议您new RestTemplate()

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
      return new RestTemplate();
  }

答案 2 :(得分:1)

如前所述,我相信您可能会错过Ribbon中的eureka-client-1配置。

首先,我会动:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

到配置类。

Ribbon配置添加到application.yml,例如:

the-eureka-client-2:
   ribbon:
     # Eureka vipAddress of the target service
     DeploymentContextBasedVipAddresses: eureka-client-2

     #listOfServers: localhost:${SERVER.PORT}
     NIWSServerListClassName: com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList

     # Interval to refresh the server list from the source (ms)
     ServerListRefreshInterval: 30000

restTemplate类中注入HystrixDemoService,而不是为每个请求实例化一个新的@Component public class HystrixDemoService { @Autowired public RestTemplate restTemplate; ... @HystrixCommand(fallbackMethod = "getFallbackCustomerName") public String getCustomerName() { URI uri = URI.create("http://eureka-client-2"); return this.restTemplate.getForObject(uri, String.class); } 。 RestTemplate是线程安全的:

the-eureka-client-2

其中eureka-client-2是映射到名称为Jersey 1的注册服务的密钥

我在博客上发表了Microservices Registration and Discovery using Spring Cloud Eureka, Ribbon and Feign,其中还包括Discovery服务器的源代码以及使用Spring MVCserver { access_log /var/log/nginx/artifactory_access.log timed_combined; error_log /var/log/nginx/artifactory_error.log; listen 80; server_name artifactory.inmz.net; location / { proxy_pass http://utils-1:8080; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; #proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Connection ""; } } 开发的两个客户端。

答案 3 :(得分:1)

以下更改对我有用。

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

@EnableDiscoveryClient
@EnableCircuitBreaker
@RestController
class HystrixDemoApplication {
    @Autowired
    HystrixDemoService hystrixDemoService;

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @RequestMapping("/")
    public String name() {
        String str = hystrixDemoService.getCustomerName();
        return "I'm A talking to "+str;
    }

}

以下是用于选择eureka-client-2 ...

实例的代码行

ServiceInstance instance = loadBalancer.choose(&#34; eureka-client-2&#34;);

@Component
public class HystrixDemoService {

    @Autowired
    private LoadBalancerClient loadBalancer;

    @HystrixCommand(fallbackMethod = "getFallbackCustomerName")
    public String getCustomerName() {
        RestTemplate restTemplate = new RestTemplate();
        ServiceInstance instance = loadBalancer.choose("eureka-client-2");
        URI uri = instance.getUri();
        return restTemplate.getForObject(uri, String.class);
    }

    public String getFallbackCustomerName() {
        System.out.println("coming inside fallback method");
        return "Resillient Customer";
    }
}