微服务入门篇(一),带你走进微服务之SpringCloudNetFix框架

目录

什么是微服务

为什么要从SpringCloudNetFix开始入门?

SpringCloudNetFix框架的微服务模块知识

Eureka

什么是Eureka

Eureka的作用

搭建Eureka环境

Eureka使用总结

Feign

什么是Feign

Feign的使用

Feign的使用总结

Ribbon

什么是Ribbon

Ribbon的使用

Ribbon的使用总结

Hystrix

什么是Hystrix

Hystrix的使用

Hystrix的使用总结

zuul

什么是Zuul

Zuul的作用

Zuul的使用

Zuul的使用总结

总结


什么是微服务

        一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建。----摘自百度百科

        小编的理解:微服务就是将原有的单个应用程序,按照业务模块与使用场景,拆分为多个子服务,实现服务之间的解耦与灵活部署、使产品的交付变得更加简单,同时微服务也提供了负载均衡、服务调用、服务注册与发现、网关、熔断等组件,可以帮我们方便快速的管理项目,所以搭建一套微服务架构何乐而不为呢?

下面我们来看,微服务下完整的架构:

        可以看到,相对于传统的架构而言,微服务架构更加灵活、加入了在各个领域内比较完善的技术,去帮我们管理项目。

为什么要从SpringCloudNetFix开始入门?

目前市面上的微服务产品有以下几种:

        Dubbo(阿里) : 目前开源于Apache ; 2012年推出;2014年停更;2015年恢复更新

        DubboX(当当基于Dubbo的更新)

        JD-hydra(京东基于Dubbo的更新)

        ServiceComb/CSE(华为2017)

        SpringCloud (Spring推出) 官网有自己的组件,但是部分没人用

        Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系 统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等, 都可以用Spring Boot的开发风格做到一键启动和部署。

        而本章节所述的SpringCloud Netfix (由Netflix开发,后面加入) 相对使用人数最多,但是现在已经停更,有朋友说,既然已经停更了,为什么还要从这些开始呢,SpringCloud Netfix是spring官网的推荐版本,虽然已经停更,但是对于我们了解微服务,从最开始的架构一步步的开始深入有利于我们学习的开展。

SpringCloudNetFix框架的微服务模块知识

以下是springcloudNetFix框架的相关组成部分:

本章节围绕eureka、feign、ribbon、hystrix、zuul的概念与原理以及使用开始介绍springcloudNetFix框架。

Eureka

什么是Eureka

        服务注册和发现,它提供了一个服务注册中心、服务发现的客户端,还有一个方便的查看所有注 册的服务的界面。 所有的服务使用Eureka的服务发现客户端来将自己注册到Eureka的服务器上。

Eureka的作用

        Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册,这样 Eureka Server 的服务注册表将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到;
        Eureka Server 之间通过复制的方式完成数据的同步,Eureka 还提供了客户端缓存机制,即使所有的 Eureka Server 都挂掉,客户端依然可以利用缓存中的信息消费其他服务的 API;
        Eureka Client:生产者或消费者;
        在应用启动后,Eureka Client 将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内(默认 90 秒)没有接收到某个节点的心跳,Eureka Server 将会进入自我保护机制;

搭建Eureka环境

1.  创建空项目,相当于一个空文件夹,存放多个微服务的项目:

2. 在空项目中创建springboot父类的maven项目,选择依赖springweb。

3. 修改pom文件中的properties标签

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>

4. 修改父项目pom中的打包方式

<packaging>pom</packaging>

 5. 创建commons项目

6. 修改commons项目的pom文件

 

<parent>
   <groupId>com.parPro</groupId>
   <artifactId>parPro</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</parent>

7. 修改commons的打包方式

<packaging>jar</packaging>

8. 创建eureka的服务端项目

9. 修改eureka服务项目的pom

<parent>
   <groupId>com.parPro</groupId>
   <artifactId>parPro</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</parent>

 10. 在eureka项目的主类上增加注解,@enableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

11.  在application.yml中配置:

#配置eureka的端口为7000
server:
  port: 7000
#配置当前项目的访问别名
spring:
  application:
  name: lc-eureka
#配置eureka的主机名称、访问地址、是否将本机注册到eureka的服务中心
eureka:
  instance:
  hostname: lc-eureka
    #配置访问eureka的地址
  client:
  service-url:
    defaultZone: http://127.0.0.1:7000/eureka
  #是否将本机注册到eureka的注册中心
  register-with-eureka: false
  fetch-registry: false

12. 启动eureka服务端项目,浏览器访问:http://127.0.0.1:7000/

13. 出现以下页面代表项目启动成功:

14. 搭建订单项目,依赖选择jpa、mysqldriver、eurekaclient

15. 修改订单项目的依赖

<parent>
   <groupId>com.parPro</groupId>
   <artifactId>parPro</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</parent>

 16. 在订单的主类上增加注解:@enableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class OrderApplication {

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

}

 17. 在application.yml中增加配置:

#配置application.yml:
  #设置端口为8000
  server:
    port: 8000
  #设置服务名称
  spring:
    application:
    name: lc-order
      #设置数据库信息
    datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  #设置eureka的信息 当前项目去哪个eureka服务中心地址注册
  eureka:
    client:
    service-url:
      defaultZone: http://127.0.0.1:7000/eureka

18. 启动eurekaserver、再启动eurekaclient,查看服务注册情况,订单服务注册进来了。

19. 创建订单的api服务,依赖选择eurekaClient

20. 修改pom文件

<parent>
   <groupId>com.parPro</groupId>
   <artifactId>parPro</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</parent>

 21. 在订单的api主类添加注解:@enableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class OrderapiApplication {

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

}

22. 配置application.yml文件

#设置端口为8200
server:
  port: 8200

#设置eureka的信息 当前项目去哪个eureka服务中心地址注册
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7000/eureka
#设置应用名称为lc-orderapi
spring:
  application:
    name: lc-orderapi

23. 浏览器访问:http://127.0.0.1:7000/,看到服务名称都被注册进来了

Eureka使用总结

以创建springboot项目的形式创建EurekaServer项目,在Eureka服务器端项目中配置:

        1. 引入Eureka服务端的依赖。

        2. 在Eureka服务端的主类上加上注解 @EnableEurekaServer,声明为当前的项目为Eureka的服务端项目。

        3. 在Eureka服务端的application.yml文件中配置Eureka的主机名称、端口、注册中心地址、是否将本机注册进Eureka注册中心。

以创建springboot项目的形式创建EurekaClient项目,在Eureka客户端项目中配置:

          1. 引入Eureka客户端的依赖。

          2. 在Eureka服务端的主类上加上注解 @EnableEurekaClient,声明为当前的项目为Eureka的客户端项目。

          3. 在Eureka服务端的项目上配置application.yml文件,配置Eureka的相关信息,指定当前的客户端向哪个地址注册服务。

Feign

什么是Feign

        服务客户端,服务之间如果需要相互访问,可以使用RestTemplate,也可以使用Feign客户端访 问,它默认会使用Ribbon来实现负载均衡。

Feign的使用

        在订单API项目中,调用订单项目提供的新增订单接口,通过访问订单API项目的路径,完成订单的新增操作,在订单项目中,我们采用jpa的方式实现新增。

1. 准备数据库表,goods、order

CREATE TABLE
    goods
    (
        gid INT NOT NULL AUTO_INCREMENT,
        gname VARCHAR(20),
        PRIMARY KEY (gid)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci;
CREATE TABLE
    orderinfo
    (
        oid INT NOT NULL AUTO_INCREMENT,
        onumber VARCHAR(20),
        PRIMARY KEY (oid)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci;

2. 在上面新建的commons项目中新增实体类orderinfo。

3. 在订单项目中导入commons中的实体类

<dependency>
   <groupId>com.commons</groupId>
   <artifactId>commons</artifactId>
          <version>0.0.1-SNAPSHOT</version>
</dependency>

4. 在ordr中编写代码

实体类代码:

@Entity
@Table(name = "orderinfo")
public class OrderInfo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int oid;
    private String onumber;

    public int getOid() {
        return oid;
    }

    @Override
    public String toString() {
        return "OrderInfo{" +
                "oid=" + oid +
                ", onumber='" + onumber + '\'' +
                '}';
    }

    public OrderInfo() {
    }

    public OrderInfo(int oid, String onumber) {
        this.oid = oid;
        this.onumber = onumber;
    }

    public void setOid(int oid) {
        this.oid = oid;
    }

    public String getOnumber() {
        return onumber;
    }

    public void setOnumber(String onumber) {
        this.onumber = onumber;
    }
}

Service代码:

@Service
public class OrderService {

    @Autowired
    OrderRepository orderRepository;

    public int addOrder(OrderInfo orderInfo){
        com.orderpro.bean.OrderInfo o1=new com.orderpro.bean.OrderInfo();
        o1.setOid(orderInfo.getOid());
        o1.setOnumber(orderInfo.getOnumber());
        com.orderpro.bean.OrderInfo save = orderRepository.save(o1);
        try{
            return save.getOid();
        }catch (Exception e){
            return -1;
        }
    }
}

Repository代码: 

public interface OrderRepository extends JpaRepository<OrderInfo,Integer> {
}

5. 在订单项目中编写controller类,对外提供服务

订单项目的controller代码:

@RestController
@CrossOrigin
@RequestMapping("/order")
public class OrderController {
    @Autowired
    OrderService orderService;


    @RequestMapping("/addOrder")
    public String addOrder(@RequestBody
OrderInfo orderInfo){
        int i = orderService.addOrder(orderInfo);
        return String.valueOf(i);
    }
}

6. 在订单API项目的主类增加注解:@EnableFeignClients

@SpringBootApplication
//@EnableDiscoveryClient//代表当前服务是消费者 调用别的服务
@EnableFeignClients
public class OrderapiApplication {

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

}

7. 在api项目增加feign的相关依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

8. 在api项目中增加controller、service

 Controller:

@RestController
@RequestMapping("order_api")
public class OrderController {

    @Autowired
    OrderFeignClient orderFeignClient;

    @RequestMapping("addOrder")
    public String addOrder(String number){
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOnumber(number);
        String result=orderFeignClient.addOrder(orderInfo);
        return result;
    }

}

Fegin接口:

//FeignClient代表 调用的是哪个服务
@FeignClient(name = "lc-order")
public interface OrderFeignClient {
    //PostMapping 调用的是哪个路径
    @PostMapping("/order/addOrder")
    String addOrder(OrderInfo orderInfo);
}

9. 在浏览器访问并传参,将参数传入,数据增加成功

http://localhost:8200/order_api/addOrder?number=123456

Feign的使用总结

在订单项目中实现以下功能:

        1. 编写实体类、service、repository、controller代码,实现订单的新增。

在订单的API项目中实现以下功能:

        1. 在主类增加注解:@EnableFeignClients

        2. 在API项目中新增Feign的依赖

        3. 在API项目中编写controller代码。

        4. 在API项目中编写Feign接口代码,

                接口上使用注解:@FeignClient(name="") 代表调用的是哪个服务 传入服务名称

                方法上使用注解:@PostMapping("/order/addOrder") 代表访问的是哪个URI

Ribbon

什么是Ribbon

        负载均衡,一个请求发送给某一个服务的应用的时候,如果一个服务启动了多个实例,就会通过 Ribbon来通过一定的负载均衡策略来发送给某一个服务实例。

Ribbon的负载均衡策略:

        RoundRobinRule ---- 轮询、默认;
        RandomRule ---- 随机;
        RetryRule ---- 重试机制;
        BestAvailableRule ---- 选择最小并发 server;
        AvailabilityFilteringRule ---- 过滤高并发、失败 server;
        WeightedResponseTimeRule ---- 根据响应时长比重选择中间值;
        ZoneAvoidanceRule ---- 判断 server 性能;

Ribbon的使用

        Feign中已经封装了ribbon,在调用时我们可以实现负载均衡,以下对ribbon的负载均衡进行验证。

  1. 在项目中copy原来的配置文件,改名为不同名称的配置文件,配置文件中定义不同的端口。

2. 定义完毕后配置启动类,读取不同的配置文件

3. 启动eureka服务,启动各个端口的服务、启动api服务。

4. 通过浏览器请求调用,发现每次请求都是遵循循环调用的规则,因为ribbon默认使用的轮询调用的规则。

Ribbon的使用总结

在订单项目中做出以下操作:

        1. 将原有的application.yml文件复制出来多份,使用不同的端口。

        2. 配置启动方式,启动项目。

        3. 通过api进行调用,查看都在哪个端口的服务打印了日志。

Hystrix

什么是Hystrix

        监控和熔断器。我们只需要在服务接口上添加Hystrix标签,就可以实现对这个接口的监控和断路 器功能。

       雪崩效应:在微服务架构中,存在多个微服务,若其中一个微服务出现故障,就很容易因为依赖关系而引发故障蔓延,最终导致整个系统瘫痪,列举:电商系统中,存在用户、订单、库存、积分、评论等微服务,用户创建一个订单,请求库存系统出货,库存系统出现问题,导致订单服务挂起或失败,在高并发的情况下,被挂起的线程导致后续请求被阻塞,最终导致订单服务不可用;
        服务熔断:当 A 服务去调用 B 服务,如果迟迟没有收到 B 服务的响应,那么就终断当前的请求,而不是一直等待下去,此时还要去监控 B 服务,当 B 服务恢复正常使用时,A 服务再发起请求;
        服务降级:A 服务调用 B 服务,没有调用成功发生熔断,那么 A 服务拿一个默认值顶着,避免给我们的用户,响应一些错误的页面;
请求缓存:对接口进行缓存,可以大大降低生产者的压力,适用更新频率低,但是访问又比较频繁的数据;
        请求合并:将客户端多个请求合并成一个请求,只发送一个 HTTP 请求,得到响应后再将请求结果分发给不同的请求,这样就可以提供传输效率;
        Netflix Hystrix 实现了断路器、线程隔离等一系列保护功能,用于隔离访问远程系统、服务或者第三方库,防止联级失败,从而提升系统的可用性与容错性;

Hystrix的使用

1. 在订单的API项目中,导入依赖:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
   <version>2.2.7.RELEASE</version>
</dependency>

2. 在订单的API项目中配置hystrix,开启熔断器,配置application.yml文件

#配置hystrix熔断器 开启熔断
feign:
  hystrix:
    enabled: true

3. 在主类中开启熔断器:@EnableHystrix

@SpringBootApplication
//@EnableDiscoveryClient//代表当前服务是消费者 调用别的服务
@EnableFeignClients//开启feign的客户端
@EnableHystrix//启动熔断器
public class OrderapiApplication {

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

}

4. 配置调用外部服务的接口,如果调用失败或者发生熔断,就走自定义的fallback方法。

在接口上方配置fallback属性,代表调用失败就走这个类中的方法:

@FeignClient(name = "lc-order",fallback = OrderFeignFallBack.class)

5. 在orderapi中新增包fallback,新增fallback类:


public class OrderFeignFallBack implements OrderFeignClient {
    @Override
    public String addOrder(OrderInfo orderInfo) {
        System.out.println("服务降级......");
        return null;
    }
}

6. 修改orderpai项目中的controller,如果返回null就代表调用失败

Hystrix的使用总结

在订单API项目中进行以下操作:

        1. 导入依赖。

        2. 配置hystrix,开启熔断。

        3. 在主类中增加注解:@EnableHystrix 启动熔断

        4. 在api的controller类上自定义调用失败时,调用哪个自定义类中的方法,通过注解实现:

                @FeignClient(name="",fallback=xxxx.class)  fallback代表调用失败执行哪个类的方法

        5. 定义调用失败时的自定义类,实现API项目中定义的对外调用服务的Feign接口,编写自定义方法。

zuul

什么是Zuul

        网关,所有的客户端请求通过这个网关访问后台的服务。他可以使用一定的路由配置来判断某一个 URL由哪个服务来处理。并从Eureka获取注册的服务来转发请求。

Zuul的作用

        将权限控制、日志收集从服务单元中抽离出去,最适合的地方是服务集群的最外端,我们需要一个功能更强大的负载均衡器,网关服务;
        网关服务是微服务架构中不可或缺的一部分,它具备统一向外提供 Rest Api、服务路由、负载均衡、权限控制等功能,为微服务架构提供了门前保护,除了安全之外,还能让服务集群具备高可用性和测试性;
        Zuul 是 NetFlix 开源的微服务网关,可以和 Eureka、Ribbon、Hystrix 等组件配合使用,其核心是一系列的过滤器;
        身份认证和安全:识别每个资源的验证要求,拒绝不符合要求的请求;
        审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图;
        动态路由:动态地将请求路由到不同的后端服务集群;
        压力测试:逐渐增加指向集群的流量;
        负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求;
        静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到集群内部;
        多区域弹性:跨越 AWS Region 进行请求路由,实现 ELB(AWS Elastic Load Balancing ---- 负载均衡服务)使用的多样化,以及让系统的边缘更贴近系统的使用者;

Zuul的使用

1. 新建springboot项目,选择依赖:eurekaClient

2. 增加依赖:

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
   <version>2.2.10.RELEASE</version>
</dependency>

3. 在主类上加上注解:@EnableZuulProxy

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ZuulProApplication {

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

}

 4. 配置application.yml

spring:
  application:
    name: ldx-zuul

server:
  port: 8080

#配置一个路由器
zuul:
  routes:
    order-api:
      path: /oapi/**
      serviceId: lc-orderapi

#从eureka获取我们的服务器的真实ip地址
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7000/eureka

  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

5. 启动eureka、order、orderapi、zuul项目

6. 访问地址:http://localhost:8088/zuul/order_api/addOrder?number=123456

Zuul的使用总结

新建springboot项目,做出以下操作:

        1. 新增zuul依赖

        2. 在主类上增加注解:@EnableZuulProxy

        3. 在application.yml文件中配置zuul

        4. 启动项目即可按照定义的方式去访问

总结

        本文源码地址:

链接:https://pan.baidu.com/s/1jK-DYbeztRqycTEnPxCq5w?pwd=bydw 
提取码:bydw 
--来自百度网盘超级会员V3的分享

        以上就是对springcloud NetFix的入门体验,后续会有springcloudAlibaba相关的文章更新,如果大家觉得写的还行,麻烦给小编点个赞,谢谢哦。

猜你喜欢

转载自blog.csdn.net/weixin_43195884/article/details/128461218
今日推荐