SpringCloud

目录

前言

一、系统架构的演变

集中式架构

垂直拆分 

分布式服务 

 流动计算架构(SOA)

 微服务

二、服务调用方式

RPC与HTTP

Http客户端工具

Spring的RestTemplate

 三、初识SpringCloud

四、微服务场景模拟

服务提供者

创建工程

编写代码

 配置

实体类

UserMapper

UserService

UserController

同理创建服务调用者

存在的问题

面临的问题

五、Eureka注册中心

认识Eureka

原理图

 入门案例

 注册到Eureka

 获取服务

Eureka详解

六、负载均衡Ribbon

负载均衡策略


前言


学习目标

  • 了解系统架构的演变
  • 了解RPC与HTTP的区别
  • 知道什么是SpringCloud
  • 独立搭建Eureka注册中心
  • 独立配置Robbin负载均衡 

一、系统架构的演变


  • 集中式架构

存在的问题:

  1. 代码耦合,开发维护困难
  2. 无法针对不同模块进行针对性优化
  3. 无法水平扩展
  4. 单点容错率低
  • 垂直拆分 

优点:

  1. 拆分分担了流量,解决并发问题
  2. 可针对不同模块优化
  3. 可水平扩展,负载均衡,容错率高

缺点:

  1. 系统间相互独立,存在重复开发 
  • 分布式服务 

 优点:

  1. 将基础服务进行抽取,提高了复用

缺点:

  1. 耦合度高,难以维护 
  •  流动计算架构(SOA)

  •  微服务

特点:

  1. 单一职责
  2. 面向服务
  3. 自治

二、服务调用方式


RPC与HTTP

RPC:Remote Produce Call远程过程调用,类似的还有RMI。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型代表

Http:http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议,也可以用来进行远程服务调用。缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。

Http客户端工具

  • HttpClient
  • OKHttp
  • URLConnection
  • 这些不同的客户端,API各不相同

Spring的RestTemplate

基于Http的客户端进行了封装,并且实现了对象与json的序列化和反序列化。

RestTemplate并没有限定Http的客户端类型,而是进行了抽象,目前常用的3种都有支持:

  • HttpClient
  • OkHttp
  • JDK原生的URLConnection(默认的)

1、在启动类注册一个RestTemplate对象

@SpringBootApplication
public class HttpDemoApplication {

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

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

2、在测试类@Autowired注入

@RunWith(SpringRunner.class)
@SpringBootTest(classes = HttpDemoApplication.class)
public class HttpDemoApplicationTests {

	@Autowired
	private RestTemplate restTemplate;

	@Test
	public void httpGet() {
        // 调用springboot案例中的rest接口
		User user = this.restTemplate.getForObject("http://localhost/user/1", User.class);
		System.out.println(user);
	}
}

 三、初识SpringCloud


它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:

  • Eureka:服务治理组件,包含服务注册中心,服务注册与发现机制的实现。(服务治理,服务注册/发现) 
  • Zuul:网关组件,提供智能路由,访问过滤功能 
  • Ribbon:客户端负载均衡的服务调用组件(客户端负载) 
  • Feign:服务调用,给予Ribbon和Hystrix的声明式服务调用组件 (声明式服务调用) 
  • Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力。(熔断、断路器,容错) 

架构图:

SpringCloud_第1张图片

四、微服务场景模拟


服务提供者

新建一个项目:itcast-service-provider,对外提供根据id查询用户的服务。

创建工程

Spring Initializr-->填写项目信息-->添加web依赖-->添加mybatis依赖-->填写项目位置

依赖已自动注入

    
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.4
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        

        
            
                
                    org.springframework.cloud
                    spring-cloud-dependencies
                    ${spring-cloud.version}
                    pom
                    import
                
                
                    org.springframework.boot
                    spring-boot-dependencies
                    ${spring-boot.version}
                    pom
                    import
                
            
        

手动添加mapper依赖

        
            tk.mybatis
            mapper-spring-boot-starter
            2.1.4
        

编写代码

  • pojo.User
  • mapper.UserMapper
  • service.UserService
  • controller.UserController
  • application.yml

 配置

# 应用名称
spring:
  application:
    name: itcast-service-provider
  datasource:
    # 数据库驱动:
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 数据库连接地址
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
    username: root
    password: root

# 应用服务 WEB 访问端口
server:
  port: 8890



#下面这些内容是为了让MyBatis映射
mybatis:
  #指定Mybatis的Mapper文件
  mapper-locations: classpath:mappers/*xml
  #指定Mybatis的实体目录
  type-aliases-package: cn.itcast.service.mybatis.pojo

实体类

@Table(name = "tb_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String name;
    private Integer age;
    private Integer sex;
    private Date birthday;
    private Date created;
    private Date updated;
    //省略get、set方法

UserMapper

import tk.mybatis.mapper.common.Mapper;


public interface UserMapper extends Mapper {

}

UserService

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryUserById(Long id){
        return this.userMapper.selectByPrimaryKey(id);
    }


}

UserController

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("{id}")
    public User queryUserById(@PathVariable("id") Long id){
        return this.userService.queryUserById(id);
    }
}

SpringCloud_第2张图片

同理创建服务调用者

SpringCloud_第3张图片

存在的问题

  • 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护

  • consumer需要记忆provider的地址,如果出现变更,可能得不到通知,地址将失效

  • consumer不清楚provider的状态,服务宕机也不知道

  • provider只有1台服务,不具备高可用性

  • 即便provider形成集群,consumer还需自己实现负载均衡

面临的问题

  • 服务管理

    • 如何自动注册和发现

    • 如何实现状态监管

    • 如何实现动态路由

  • 服务如何实现负载均衡

  • 服务如何解决容灾问题

  • 服务如何实现统一配置

五、Eureka注册中心

认识Eureka

Eureka就好比是滴滴,负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。

同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。

实现了服务的自动注册、发现、状态监控。

原理图

SpringCloud_第4张图片

  • Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址

  • 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)

  • 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新

  • 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态  

 入门案例

spring快速搭建-->选择Cloud Discovery-->选择依赖Eureka Service

配置

# 应用名称
spring:
  application:
    name: itcast-eureka #将来作为微服务名称注入到eureka容器


server:
  port: 10086

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka

引导类

@SpringBootApplication
@EnableEurekaServer//启用euerka服务端
public class ItcastEurekaApplication {

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

}

启动访问http://localhost:10086

SpringCloud_第5张图片

 注册到Eureka

修改itcast-service-provider工程

  1. 在pom.xml中,添加springcloud的相关依赖。

  2. 在application.yml中,添加springcloud的相关依赖。

  3. 在引导类上添加注解,把服务注入到eureka注册中心。

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
#.yml
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
//引导类
@SpringBootApplication
@EnableDiscoveryClient//启用eureka客户端
public class ItcastServiceProviderApplication {

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

}

启动重新访问 http://localhost:10086

 获取服务

客户端消费者注册同理,获取服务修改controller

@Controller
@RequestMapping("consumer/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient; // eureka客户端,可以获取到eureka中服务的信息

    @GetMapping
    @ResponseBody
    public User queryUserById(@RequestParam("id") Long id){
        // 根据服务名称,获取服务实例。有可能是集群,所以是service实例集合
        List instances = discoveryClient.getInstances("service-provider");
        // 因为只有一个Service-provider。所以获取第一个实例
        ServiceInstance instance = instances.get(0);
        // 获取ip和端口信息,拼接成服务地址
        String baseUrl = "http://" + instance.getHost() + ":" + instance.getPort() + "/user/" + id;
        User user = this.restTemplate.getForObject(baseUrl, User.class);
        return user;
    }

}

Eureka详解

基础架构

  • 服务注册中心

    Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的itcast-eureka。

  • 服务提供者

    提供服务的应用,可以是SpringBoot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可。本例中就是我们实现的itcast-service-provider。

  • 服务消费者

    消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。本例中就是我们实现的itcast-service-consumer。

高可用

Eureka Server即服务的注册中心,在刚才的案例中,我们只有一个EurekaServer,事实上EurekaServer也可以是一个集群,形成高可用的Eureka中心。

多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。

六、负载均衡Ribbon

在案例中,启动了一个itcast-service-provider,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。

但是实际环境中,往往会开启很多个itcast-service-provider的集群。此时获取的服务列表中就会有多个,到底该访问哪一个呢?

一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。

什么是ribbon

SpringCloud_第6张图片

负载均衡策略

SpringBoot也提供了修改负载均衡规则的配置入口,在itcast-service-consumer的application.yml中添加如下配置:  

service-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的实现类。

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