更新時間:2021-12-28 11:35:02 來源:動力節點 瀏覽2260次
服務注冊是微服務架構中的關鍵組件,它允許應用程序動態發現和調用注冊的服務,而不是手動配置使用的服務。在這篇文中,我們將研究 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("http://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,它為我們提供了一個類型安全的 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 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 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服務的信息。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習