专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 SpringCloud注册中心的介绍

SpringCloud注册中心的介绍

更新时间:2021-12-28 11:35:02 来源:赢咖4 浏览1637次

服务注册是微服务架构中的关键组件,它允许应用程序动态发现和调用注册的服务,而不是手动配置使用的服务。在这篇文中,我们将研究 Eureka 和 Spring Cloud Services 中的 Service Registry(基于 Eureka)。Eureka 来自 Netflix,有两个组件 Eureka Server 和 Eureka Client。Eureka Server 可以使用@EnableEurekaServer注解嵌入到 Spring Boot 应用程序中,但在这里我们研究如何使用安装了Spring Cloud CLI扩展的Spring Boot CLI来运行它。 该名单可以开始提供服务

spring cloud --list

spring cloud --list
configserver dataflow eureka h2 hystrixdashboard kafka stubrunner zipkin

通过跑步

spring cloud eureka

尤里卡将在 http://localhost:8761

我们customser-service和order-service这两个Eureka ClientS式的customer-service调用order-service。

为了向这些服务注册,Eureka Server我们需要包含以下依赖项:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

该customer-service实施如下:

@SpringBootApplication
public class CustomerService {
    public static void main(String[] args) {
        SpringApplication.run(CustomerService.class, args);
    }
    @Configuration
    static class CustomerConfig {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    @RestController
    @Slf4j
    static class CustomerController {
        private static final String TEMPLATE = UriComponentsBuilder.fromUriString("//order-service/orders")
                .queryParam("customerId", "{customerId}").build().toUriString();
        private final RestTemplate restTemplate;
        private final CustomerRepository customerRepository;
        public CustomerController(RestTemplate restTemplate, CustomerRepository customerRepository) {
            this.restTemplate = restTemplate;
            this.customerRepository = customerRepository;
        }
        @GetMapping("/customers/{id}")
        public ResponseEntity<Customer> getCustomer(@PathVariable Long id) {
            log.info("getCustomer with id {}", id);
            Customer customer = customerRepository.getCustomer(id);
            if (customer == null) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            Order order = restTemplate.getForObject(TEMPLATE, Order.class, id);
            if (order != null) {
                customer.setOrder(new Order(order.getDetails(), order.getTime()));
            }
            return new ResponseEntity<>(customer, HttpStatus.OK);
        }
    }
    @Data
    @AllArgsConstructor
    static class Customer {
        Long id;
        String name;
        Order order;
    }
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class Order {
        String details;
        LocalDateTime time;
    }
}

我们不再需要@EnableDiscoveryClient注解,当DiscoveryClient实现(如本文中使用的Spring Cloud Netflix Eureka)在类路径上可用时,Spring Boot 应用程序将自己注册到服务注册中心。(更多详情请见EurekaClientAutoConfiguration)

默认情况下,Spring Boot 应用程序会自动注册自己。有一个方便的/service-registry执行器端点,以便查询和注​​册/取消注册服务注册表

在我们的示例中,如果我们想order-service停止服务,我们可以使用:

echo '{"status":"OUT_OF_SERVICE"}' | http post :8081/actuator/service-registry

在此之后,customer-service将能够调用order-service大约 30 秒,因为这是Eureka Clients 查找注册表信息以定位其服务并进行远程调用的默认设置。

将RestTemplate不再通过自动配置创建的,在customer-service我们需要创建一个。我们使用@LoadBalanced注释来确保它在order-service实例之间进行负载平衡。

使用 Feign

另一种调用下游服务的方法是使用Feign,它为我们提供了一个类型安全的 HTTP 客户端。

@SpringBootApplication
@EnableFeignClients
public class CustomerServiceFeign {
    public static void main(String[] args) {
        SpringApplication.run(CustomerServiceFeign.class, args);
    }
    @RestController
    @Slf4j
    static class CustomerController {
        private final OrderServiceClient orderServiceClient;
        private final CustomerRepository customerRepository;
        public CustomerController(OrderServiceClient orderServiceClient, CustomerRepository customerRepository) {
            this.orderServiceClient = orderServiceClient;
            this.customerRepository = customerRepository;
        }
        @GetMapping("/customers/{id}")
        public ResponseEntity<Customer> getCustomer(@PathVariable Long id) {
            log.info("getCustomer with id {}", id);
            Customer customer = customerRepository.getCustomer(id);
            if (customer == null) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            Order order = orderServiceClient.getOrder(id);
            if (order != null) {
                customer.setOrder(order.getDetails());
            }
            return new ResponseEntity<>(customer, HttpStatus.OK);
        }
    }
    @FeignClient("order-service")
    interface OrderServiceClient {
        @GetMapping("/orders")
        Order getOrder(@RequestParam("customerId") Long id);
    }   
}

使用@FeignClient接口上的注释,实际实现是在运行时提供的。在后台创建了一个功能区负载平衡器。

Spring Boot 管理员

Spring Boot Admin是管理 Spring Boot 微服务的绝佳工具。不幸的是,Spring Boot / Spring Cloud CLI 尚不支持它,但我们可以轻松设置 Spring Boot 管理服务器。创建 Spring Boot 应用程序后,我们需要包含以下依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

@SpringBootApplication
@EnableAdminServer
public class SpringBootAdmin {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAdmin.class, args);
    }
    @Configuration
    static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        private final String adminContextPath;
        public WebSecurityConfig(AdminServerProperties adminServerProperties) {
            this.adminContextPath = adminServerProperties.getContextPath();
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
            successHandler.setDefaultTargetUrl(adminContextPath + "/");
            successHandler.setTargetUrlParameter("redirectTo");
            http.authorizeRequests()
                    .antMatchers(adminContextPath + "/assets/**").permitAll()
                    .antMatchers(adminContextPath + "/login").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
                    .logout().logoutUrl(adminContextPath + "/logout").and()
                    .httpBasic().and()
                    .csrf().disable();
        }
    }
}

Pivotal Cloud Foundry (PCF) 上的服务注册表

到现在为止还挺好。让我们在Pivotal Web 服务(由 Pivotal 托管的 PCF 实例)上设置这个小示例,我们将在其中使用Spring Cloud Services的 Service Registry 服务(trial计划)

首先,我们需要安装CloudFoundry CLI并创建一个Pivotal Web Services帐户。

我们创建一个service-registry使用以下命令命名的服务实例

cf cs p-service-registry trial service-registry

然后我们需要将以下依赖项包含到Eureka Client应用程序中 ( customer-service, customer-service-feign, order-service, spring-boot-admin)

<dependency>
    <groupId>io.pivotal.spring.cloud</groupId>
    <artifactId>spring-cloud-services-starter-service-registry</artifactId>
</dependency>

manifest.yml为所有服务创建文件很方便。因为customer-service是

applications:
- name: customer-service
  memory: 756M
  instances: 1
  path: target/customer-service.jar
  buildpack: java_buildpack
  services:
  - service-registry

在构建应用程序后,mvn clean package我们可以部署

cf push --random-route

部署完所有服务后,我们应该会看到如下内容:

cf apps
name                     requested state   instances   memory   disk   urls
customer-service         started           1/1         756M     1G     customer-service-shy-mandrill.cfapps.io
customer-service-feign   started           1/1         756M     1G     customer-service-feign-cheerful-hartebeest.cfapps.io
order-service            started           1/1         756M     1G     order-service-appreciative-koala.cfapps.io
spring-boot-admin        started           1/1         756M     1G     spring-boot-admin-anxious-leopard.cfapps.io

我们可以测试服务:

http customer-service-shy-mandrill.cfapps.io/customers/1
{
    "id": 1,
    "name": "Paul Molive",
    "order": {
        "details": "Grilled Chicken Sandwich",
        "time": "2018-08-10T07:32:38.463"
    }
}

Spring Boot 管理控制台可用:

在环境变量中设置密码的好习惯。在 Spring Boot Admin 中,我们使用了以下内容:

spring:
  security:
    user:
      name: admin
      password: ${ADMIN_PASSWORD:admin}

我们在 Pivotal Cloud Foundry的空间中ADMIN_PASSWORD为spring-boot-admin应用程序设置了development

cf set-env spring-boot-admin admin s3cr3t

当customer-service绑定到service-registry服务实例时,在VCAP_SERVICES环境变量中设置了连接详细信息。

cf env customer-service
{
 "VCAP_SERVICES": {
  "p-service-registry": [
   {
    "binding_name": null,
    "credentials": {
     "access_token_uri": "https://p-spring-cloud-services.uaa.run.pivotal.io/oauth/token",
     "client_id": "p-service-registry-f31ae316-8f1c-4a2d-84ab-02062a0c5aae",
     "client_secret": "ygjAdaV6Gnff",
     "uri": "https://eureka-aa041440-7a75-45b8-bbba-435c79e4ff66.cfapps.io"
    },
    "instance_name": "service-registry",
    "label": "p-service-registry",
    "name": "service-registry",
    "plan": "trial",
    "provider": null,
    "syslog_drain_url": null,
    "tags": [
     "eureka",
     "discovery",
     "registry",
     "spring-cloud"
    ],
    "volume_mounts": []
   }
  ]
 }
}

由于我们没有配置eureka.client.service-url.defaultZone它,它是如何从VCAP_SERVICES? 包含在EurekaServiceConnector提供eureka.client.*属性的 中,该属性EurekaServiceInfo封装了如何访问service-registry服务的信息。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>