SpringCloud学习二

基本介绍:

Eureka Server(Eureka 服务端)是Netflix开源的一款用于构建分布式系统中的服务发现和注册中心的组件。它在微服务架构中扮演着关键的角色,允许不同的微服务应用程序注册自己,并查询其他服务的位置信息,以便它们可以相互通信。

以下是关于Eureka Server的一些重要介绍和特点:

  1. 服务注册和发现:Eureka Server允许微服务应用程序在启动时将自己注册到Eureka注册中心,以便其他服务可以发现它们。注册的服务可以提供有关其名称、IP地址、端口和健康状态等信息。

  2. 健康检查:Eureka Server支持对注册的服务进行健康检查,以便在服务不可用时将其从注册表中移除。这有助于避免将请求路由到不可用的服务实例。

  3. 客户端负载均衡:Eureka客户端库可用于在微服务消费者之间实现负载均衡。消费者可以从Eureka Server中获取可用服务实例的列表,并选择一个进行调用。

  4. 自我保护机制:Eureka Server具有自我保护机制,可以在某些情况下防止服务注册表中的整体故障。如果Eureka Server在一段时间内无法收到心跳信号,它不会立即删除该服务,而是将其标记为"不健康",并继续提供服务。这有助于防止因网络故障或其他问题导致的误删除服务。

  5. 集群支持:Eureka Server支持构建高可用性集群,其中多个Eureka Server实例一起工作,以确保可用性和冗余。

  6. Spring Cloud集成:Eureka Server通常与Spring Cloud一起使用,以便轻松构建和管理微服务架构。Spring Cloud提供了对Eureka的集成支持,使开发者能够更容易地使用Eureka进行服务注册和发现。

Eureka Client是一个用于与Eureka Server进行通信的库或模块,通常用于微服务架构中的服务提供者和服务消费者。Eureka Client允许微服务应用程序向Eureka Server注册自己并查询其他已注册的服务的位置信息,以便实现服务的发现和负载均衡。

以下是关于Eureka Client的一些重要信息和功能:

  1. 服务注册:服务提供者(通常是一个微服务应用程序)使用Eureka Client来向Eureka Server注册自己。注册包括提供服务的名称、IP地址、端口号以及其他元数据信息。一旦注册,其他服务就可以通过Eureka Server发现并调用该服务。

  2. 服务发现:服务消费者使用Eureka Client来从Eureka Server中获取可用服务实例的列表。Eureka Client通过查询Eureka Server来获取这些信息,并维护本地缓存以实现快速访问。消费者可以根据服务的名称来发现可用的服务实例,并选择一个实例进行调用。

  3. 负载均衡:Eureka Client通常与负载均衡器结合使用,以确保请求均匀地分配到多个服务实例中。通过从Eureka Server获取实例列表并使用负载均衡策略选择实例,Eureka Client可以帮助分散服务调用的负载,提高系统性能和可用性。

  4. 健康检查:Eureka Client定期向Eureka Server发送心跳信号,以表明它仍然处于活动状态。Eureka Server可以使用这些心跳信号来检测服务实例的健康状况,并在需要时将其标记为不健康或下线。

  5. 故障转移:如果Eureka Client无法连接到Eureka Server,它会尝试与其他Eureka Server实例建立连接(如果配置了多个)。这有助于提高系统的可用性,即使一个Eureka Server实例不可用,服务注册和发现仍然可以正常工作。

  6. Spring Cloud集成:Eureka Client通常与Spring Cloud一起使用,以便轻松构建和管理微服务架构。Spring Cloud提供了对Eureka Client的集成支持,使开发者能够更容易地将服务注册到Eureka Server和发现其他服务。

Eureka Client 代码实现

基本结构:

SpringCloud学习二_第1张图片

  • 创建 Module ,pom.xml


    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
        2.0.2.RELEASE
    
  • 创建配置文件 application.yml,添加 Eureka Client 相关配置

server:
  port: 8010
spring:
  application:
    name: provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

属性说明:

spring.application.name:当前服务注册在 Eureka Server 上的名称。

eureka.client.service-url.defaultZone:注册中心的访问地址。

eureka.instance.prefer-ip-address:是否将当前服务的 IP 注册到 Eureka Server。

  • 创建启动类

package com.southwind;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
@SpringBootApplication
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class,args);
    }
}
  • 实体类

package com.southwind.entity;
​
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private long id;
    private String name;
    private int age;
}
  • Repository

package com.southwind.repository;
​
import com.southwind.entity.Student;
​
import java.util.Collection;
​
public interface StudentRepository {
    public Collection findAll();
    public Student findById(long id);
    public void saveOrUpdate(Student student);
    public void deleteById(long id);
}
  • RepositoryImpl

package com.southwind.repository.impl;
​
import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.stereotype.Repository;
​
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
​
@Repository
public class StudentRepositoryImpl implements StudentRepository {
​
    private static Map studentMap;
​
    static {
        studentMap = new HashMap<>();
        studentMap.put(1L,new Student(1L,"张三",22));
        studentMap.put(2L,new Student(2L,"李四",23));
        studentMap.put(3L,new Student(3L,"王五",24));
    }
​
    @Override
    public Collection findAll() {
        return studentMap.values();
    }
​
    @Override
    public Student findById(long id) {
        return studentMap.get(id);
    }
​
    @Override
    public void saveOrUpdate(Student student) {
        studentMap.put(student.getId(),student);
    }
​
    @Override
    public void deleteById(long id) {
        studentMap.remove(id);
    }
}
  • Handler

package com.southwind.controller;
​
import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
​
import java.util.Collection;
​
@RestController
@RequestMapping("/student")
public class StudentHandler {
    @Autowired
    private StudentRepository studentRepository;
​
    @GetMapping("/findAll")
    public Collection findAll(){
        return studentRepository.findAll();
    }
​
    @GetMapping("/findById/{id}")
    public Student findById(@PathVariable("id") long id){
        return studentRepository.findById(id);
    }
​
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        studentRepository.saveOrUpdate(student);
    }
​
    @PutMapping("/update")
    public void update(@RequestBody Student student){
        studentRepository.saveOrUpdate(student);
    }
​
    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") long id){
        studentRepository.deleteById(id);
    }
}

运行启动类,先运行Eurek启动类:

SpringCloud学习二_第2张图片

访问8761端口:

SpringCloud学习二_第3张图片

SpringCloud学习二_第4张图片

RestTemplate基本介绍:

在Spring Cloud中,RestTemplate是一个常用的HTTP客户端工具,用于在微服务架构中进行服务间的通信。Spring Cloud通过提供一些额外的功能来增强RestTemplate,以便更轻松地与分布式系统中的微服务进行交互。以下是一些关于在Spring Cloud中使用RestTemplate的注意事项:

  1. 负载均衡: Spring Cloud集成了负载均衡器Ribbon,可以让RestTemplate自动选择要调用的服务实例。您可以使用服务的名称而不是硬编码的URL来发送请求。例如:

    restTemplate.getForObject("http://my-service/api/resource", String.class);

    在这个例子中,my-service是服务的名称,Ribbon会自动选择一个可用的实例进行调用。

  2. 服务发现: Spring Cloud集成了Eureka或其他服务注册中心,可以让RestTemplate自动发现可用的服务实例。这意味着您不需要手动配置每个服务的主机和端口,而是使用服务的名称来访问它们。

  3. 请求拦截器: Spring Cloud允许您添加拦截器来处理请求和响应,例如添加身份验证信息、记录请求日志等。这可以通过实现ClientHttpRequestInterceptor接口来实现。

  4. 错误处理: 在Spring Cloud中,RestTemplate通常会捕获HTTP错误,并将它们封装为HttpClientErrorException(如4xx错误)或HttpServerErrorException(如5xx错误)等异常。这样,您可以更容易地处理HTTP错误。

  5. 配置管理: 使用Spring Cloud Config,您可以在不同的环境中为RestTemplate配置不同的属性,如超时时间、连接池大小等。

  6. 断路器模式: Spring Cloud集成了Hystrix,可以通过@HystrixCommand注解来保护RestTemplate的调用,以便在服务不可用时进行降级或错误处理。

RestTemplate 的使用

结构图:

SpringCloud学习二_第5张图片

  • 什么是 RestTemplate?

RestTemplate 是 Spring 框架提供的基于 REST 的服务组件,底层是对 HTTP 请求及响应进行了封装,提供了很多访问 RETS 服务的方法,可以简化代码开发。

  • 如何使用 RestTemplate?

1、创建 Maven 工程,pom.xml。

2、创建实体类

package com.southwind.entity;
​
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private long id;
    private String name;
    private int age;
}

3、Handler

package com.southwind.controller;
​
import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
​
import java.util.Collection;
​
@RestController
@RequestMapping("/rest")
public class RestHandler {
    @Autowired
    private RestTemplate restTemplate;
​
    @GetMapping("/findAll")
    public Collection findAll(){
        return restTemplate.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody();
    }
​
    @GetMapping("/findAll2")
    public Collection findAll2(){
        return restTemplate.getForObject("http://localhost:8010/student/findAll",Collection.class);
    }
​
    @GetMapping("/findById/{id}")
    public Student findById(@PathVariable("id") long id){
        return restTemplate.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id).getBody();
    }
​
    @GetMapping("/findById2/{id}")
    public Student findById2(@PathVariable("id") long id){
        return restTemplate.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id);
    }
​
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        restTemplate.postForEntity("http://localhost:8010/student/save",student,null).getBody();
    }
​
    @PostMapping("/save2")
    public void save2(@RequestBody Student student){
        restTemplate.postForObject("http://localhost:8010/student/save",student,null);
    }
​
    @PutMapping("/update")
    public void update(@RequestBody Student student){
        restTemplate.put("http://localhost:8010/student/update",student);
    }
​
    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") long id){
        restTemplate.delete("http://localhost:8010/student/deleteById/{id}",id);
    }
}

4、启动类

package com.southwind;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
​
@SpringBootApplication
public class RestTemplateApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestTemplateApplication.class,args);
    }
​
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

Consumer基本介绍:

服务消费者(Consumer)是微服务架构中的一种角色,它用于调用和使用提供者服务的功能。服务消费者通常不负责实际的业务逻辑处理,而是依赖于提供者服务来获取所需的数据或执行操作。在微服务架构中,服务消费者通常使用HTTP请求或其他通信协议与提供者服务进行通信。

以下是有关服务消费者的一些关键概念和特点:

  1. 依赖性: 服务消费者依赖于一个或多个提供者服务,它们是整个系统中的客户端。

  2. 服务发现: 为了与提供者服务通信,服务消费者通常需要了解提供者服务的位置信息。这可以通过服务发现机制来实现,其中服务提供者会将自己注册到服务注册中心(如Eureka),而服务消费者可以查询注册中心来获取可用的提供者服务列表。

  3. 负载均衡: 微服务架构通常包含多个相同功能的提供者服务实例,服务消费者可以使用负载均衡来分发请求,以确保高可用性和性能。

  4. 断路器: 为了防止服务消费者在提供者服务不可用或出现故障时受到影响,可以使用断路器模式(如Hystrix)来实现容错和降级。断路器会在一段时间内监控服务提供者的响应,并在需要时停止向不可用的服务实例发送请求。

  5. 请求和响应处理: 服务消费者使用HTTP客户端(如RestTemplate)来发送请求到提供者服务,并处理来自提供者的响应。通常,响应会被解析并转换为服务消费者的领域对象。

  6. 容器化: 服务消费者通常是运行在容器中的,如Docker容器。这使得它们可以轻松地部署和扩展。

  7. 配置管理: 服务消费者需要配置和管理与提供者服务的通信方式,包括URL、端口、超时等。Spring Cloud Config等工具可以用于集中管理这些配置。

  8. 安全性: 通信通常需要进行安全处理,以确保数据的机密性和完整性。安全性可以通过HTTPS、OAuth2等方式来实现。

  9. 监控和追踪: 服务消费者可能需要监控其与提供者服务之间的通信,并记录请求和响应以进行追踪和故障排除。Spring Cloud Sleuth和Zipkin等工具可用于实现分布式跟踪。

服务消费者 consumer

结构图:

SpringCloud学习二_第6张图片

  • 创建 Maven 工程,pom.xml


    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
        2.0.2.RELEASE
    
  • 创建配置文件 application.yml

server:
  port: 8020
spring:
  application:
    name: consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
  • 创建启动类

package com.southwind;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
​
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
​
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • Handler

package com.southwind.controller;
​
import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
​
import java.util.Collection;
​
@RestController
@RequestMapping("/consumer")
public class ConsumerHandler {
    @Autowired
    private RestTemplate restTemplate;
​
    @GetMapping("/findAll")
    public Collection findAll(){
        return restTemplate.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody();
    }
​
    @GetMapping("/findAll2")
    public Collection findAll2(){
        return restTemplate.getForObject("http://localhost:8010/student/findAll",Collection.class);
    }
​
    @GetMapping("/findById/{id}")
    public Student findById(@PathVariable("id") long id){
        return restTemplate.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id).getBody();
    }
​
    @GetMapping("/findById2/{id}")
    public Student findById2(@PathVariable("id") long id){
        return restTemplate.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id);
    }
​
    @PostMapping("/save")
    public void save(@RequestBody Student student){
        restTemplate.postForEntity("http://localhost:8010/student/save",student,null).getBody();
    }
​
    @PostMapping("/save2")
    public void save2(@RequestBody Student student){
        restTemplate.postForObject("http://localhost:8010/student/save",student,null);
    }
​
    @PutMapping("/update")
    public void update(@RequestBody Student student){
        restTemplate.put("http://localhost:8010/student/update",student);
    }
​
    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") long id){
        restTemplate.delete("http://localhost:8010/student/deleteById/{id}",id);
    }
}

你可能感兴趣的:(spring,cloud,学习,java)