0
点赞
收藏
分享

微信扫一扫

Eureka使用

非凡兔 2022-01-20 阅读 107

1.eureka注册中心

注册中心服务端主要对外提供了三个功能:
服务注册:
服务提供者启动时,会通过 Eureka Client 向 Eureka Server 注册信息,Eureka Server 会存储该服务的信息,Eureka Server 内部有二层缓存机制来维护整个注册表。
提供注册表:
服务消费者在调用服务时,如果 Eureka Client 没有缓存注册表的话,会从 Eureka Server 获取最新的注册表。
同步状态:
Eureka Client 通过注册、心跳机制和 Eureka Server 同步当前客户端的状态。

2.创建项目

2.1添加eureka依赖

在这里插入图片描述

2.2修改pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud1</artifactId>
        <groupId>cn.tedu</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sp05-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sp05-eureka</name>
    <description>Demo project for Spring Boot</description>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

2.3修改application.yml文件

# 应用名称

spring:
  pplication:
  name: eureka-server
#2001,3001,4001,5001,6001
server:
  port: 2001
eureka:
  server:
    enable-self-preservation: false   #禁用自我保护机制
  instance:
    hostname: eureka1 #主机名
  client:
    register-with-eureka: false   #不向自己注册
    fetch-registry: false   #不从自己拉取

Eureka四条运行机制:

1.注册:客户端会一次一次的反复注册,直到注册成功为止。
2.拉取:客户端每隔30秒,重复的拉取、刷新本地缓存的注册表。
3.心跳:客户端每隔30秒向服务器发送心跳,如果服务器连续3次收不到一个服务的心跳,就会删除该服务的注册信息。
4.自我保护模式:
网络不稳定,或网络中断时,15分钟内85%服务器都出现心跳异常,会进入自动保护模式;
这种特殊情况下,会保护所有注册信息不删除;
等待网络回复正常后,自动退出保护模式;
开发调试期间应该禁用保护模式,避免影响测试。

2.4启动类添加@EnableEurekaServer注解

2.5为02、03、04工程添加依赖

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

2.6 02工程配置文件添加

spring:
  application:
    name: user-service


server:
  port: 8101
#用户的demo数据
#[{id:7,username:xx,password:xx},{8..},{9..}]
sp:
  user-service:
    users: "[{\"id\":7, \"username\":\"abc\",\"password\":\"123\"},
            {\"id\":8, \"username\":\"def\",\"password\":\"456\"},
            {\"id\":9, \"username\":\"ghi\",\"password\":\"789\"}]"
#/eureka 子路径是客户端调用的 REST API 路径,浏览器不能访问
        eureka:
          client:
            service-url:
              defaultZone: http://eureka1:2001/eureka

在这里插入图片描述

  • defaultZone:默认地点,也可以从云服务商购买不同地点的eurea服务

2.7修改 hosts 文件,添加 eureka 域名映射

C:\Windows\System32\drivers\etc\hosts 管理员打开
添加内容:

127.0.0.1       eureka1
127.0.0.1       eureka2

2.8启动,并访问测试

http://eureka1:2001

3.Eureka 和 “服务提供者”的高可用

在这里插入图片描述

3.1item-service 高可用

启动参数 --server.port 可以覆盖yml中的端口配置;
通过启动参数设置启动的端口:

java -jar item.jar --server.port=8001
java -jar item.jar --server.port=8002

在这里插入图片描述
启动测试:
在这里插入图片描述

3.2Erueka高可用

添加两个服务器的 profile 配置文件:
application-eureka1.yml:

#2001,3001,4001,5001,6001
server:
  port: 2001
eureka:
  instance:
    hostname: eureka1 #主机名
  client:
    register-with-eureka: true   #false不向自己注册,profile的配置会覆盖公用配置
    fetch-registry: true   #false不从自己拉取,profile的配置会覆盖公用配置
    service-url:
      defaultZone: http://eureka2:2002/eureka  #eureka1启动时向eureka2注册

application-eureka2.yml:

#2001,3001,4001,5001,6001
server:
  port: 2002
eureka:
  instance:
    hostname: eureka2 #主机名
  client:
    register-with-eureka: true   #false不向自己注册,profile的配置会覆盖公用配置
    fetch-registry: true   #false不从自己拉取,profile的配置会覆盖公用配置
    service-url:
      defaultZone: http://eureka1:2001/eureka  #eureka1启动时向eureka2注册

在这里插入图片描述
访问 eureka 服务器,查看注册信息:
http://eureka1:2001/
在这里插入图片描述
http://eureka2:2002/
在这里插入图片描述

3.3eureka客户端注册时,向两个服务器注册

修改以下微服务:
sp02-itemservice
sp03-userservice
sp04-orderservice

  #/eureka 子路径是客户端调用的 REST API 路径,浏览器不能访问
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka

4. 02orderservice远程调用02和03

4.1添加feign依赖

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

4.2启动类添加@EbableFeignClients注解

4.3添加两个远程调用接口

package cn.tedu.sp04.feign;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.web.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

/**
 * 1.调用哪个服务
 * 2.调用这个服务的哪个路径
 * 3.向这个路径提交什么参数
 * */

@FeignClient(name="item-service",contextId = "itemClient")
public interface ItemClient {
    //获取订单的商品列表
    @GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable("orderId") String orderId);

    //减少商品库存
    @PostMapping("/decreaseNumber")
    JsonResult<?> decreaseNumber(@RequestBody List<Item> items);
}
package cn.tedu.sp04.feign;

import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.web.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "user-service",contextId = "userClient")
public interface UserClient {
    //获取用户
    @GetMapping("/{userId}")
    JsonResult<User> getUser(@PathVariable("userId") Integer userId);
    //增加用户积分
    @GetMapping("/{userId}/score") //?score=1000
    JsonResult<?> addScore(@PathVariable("userId") Integer userId,
                           @RequestParam Integer score);
}

4.4在订单实现类远程调用两个接口

在这里插入图片描述

5.Feign集成Ribbon

Ribbon提供负载均衡和重试的功能
Ribbon重试:调用后台服务失败(异常、超时、宕机),可以自动发起重试调用。
随机向一台服务器请求,请求失败(重试次数默认为0)则会更换服务器(更换服务器次数默认为1)。
单台服务器的重试次数MaxAutoRetries(默认0)(x),更换服务器的次数 MaxAutoRetriesNextServer(默认1)(y),最大请求次数(x+1)*(y+1)
在itemController模拟阻塞运算:

//模拟阻塞运算
if (Math.random()<0.9){//90%概率执行阻塞代码
    //阻塞时长随机0-5秒
    int t = new Random().nextInt(5000);
    log.info("阻塞:"+t);
    Thread.sleep(t);
}
  • ribbon.MaxAutoRetries:重试次数,默认为0
  • ribbon.MaxAutoRetriesNextServer:更换服务器次数,默认为1
  • ribbon.ReadTimeout:超时时间,默认1000
  • ribbon.ConnectTimeout:与后台服务器建立连接的超时时间,默认1000
  • ribbon.OkToRetryOnAllOperations:是否对所有类型请求都重试,默认只对GET请求重试

6.Zuul API网关

统一的入口:

1.新建spring模块:sp06-zuul

选择eureka client依赖

2.添加依赖:zuul、eureka client、sp01

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud1</artifactId>
        <groupId>cn.tedu</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sp06-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sp06-zuul</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>
</project>

3.配置yml:

# 应用名称
spring:
  application:
    name: zuul
# 2001,3001,4001,5001,6001

server:
  port: 3001
eureka:
  client:
    service-url:
      defaultZone: http://eureks1:2001/eureka, http://eureks2:2002/eureka,
#路由转发规则
#最好手动配置
zuul:
  routes:
    item-service: /item-service/**  # **包含深层子路径,*只含当前一层路径
    user-service: /user-service/**
    order-service: /order-service/**

4.启动类加@EnableZuulProxy注解

启用zuul网关
先启动两个eureka服务,启动02、03、04,最后启动zuul

7.统一权限校验

模拟登录检查:

http://localhost:3001/order-service/order123456 没有登录,不允许访问
http://localhost:3001/order-service/order123456?token=fdshnkj 已经登录可以访问

1.新建过滤器,继承ZuulFilter
2.按照规则实现ZuulFilter
3.添加注解@Component

  • zuul的自动配置类会自动配置过滤器

添加过滤类:

@Component
public class AccessFilter extends ZuulFilter {
    //过滤器类型,pre前置,routing 运行 post后置,error错误
    @Override
    public String filterType() {
        //return "pre";
        return FilterConstants.PRE_TYPE;//前置过滤器
    }

    //过滤器顺序号
    @Override
    public int filterOrder() {
        return 6;//放在第6位
    }

    //针对当前请求,是否执行过滤代码
    @Override
    public boolean shouldFilter() {
        //调用item-service需要判断权限

        //否则,不判断权限,直接跳过过滤代码

        //获取请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //从上下文对象获得调用的服务id
        String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);//("serviceId)
        //如果服务id是 item-service,返回true,否则返回false
        return "item-service".equalsIgnoreCase(serviceId);//IgnoreCase忽略大小写

    }

    //过滤代码
    @Override
    public Object run() throws ZuulException {
        // http://localhost:3001/order-service/order123456?token=fdshnkj
        //获取请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();
        //从上下文获得request对象
        HttpServletRequest request = ctx.getRequest();
        //从request取出token参数
        String token = request.getParameter("token");
        //如果没有token,null,""
        if (StringUtils.isBlank(token)) {
            //阻止继续调用
            ctx.setSendZuulResponse(false);
            //直接向客户端返回响应
            String json = JsonResult.build().code(400).msg("未登录").toString();
            ctx.addZuulResponseHeader("Content-Type", "application/json;charset=UTF-8");
            ctx.setResponseBody(json);
        }
        return null;
    }
}

Zuul集成Ribbon

  • 默认启用了负载均衡
  • 默认不启用重试,一般不在网关添加重试功能,否则可能造成后台服务器压力过大,出现大面积故障,重试功能应该尽量靠后添加

Zuul启用重试:

1.添加依赖:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

2.修改配置文件:
在这里插入图片描述

Zuul集成Hystrix

向后台服务转发调用,使用Hystrix进行容错和限流
Zuul默认已经启用了Hystrix。不做任何配置

8.Hystrix

容错(降级)和限流(熔断)工具

Zuul集成Hystrix添加降级

1.新建降级类,实现FallBackProvider接口
2.按接口规则实现
3.添加注解:@Component
zuul的自动配置类可以完成自动配置

Hystrix熔断:

流量过大,出现故障,可以熔断,断开链路,减轻后台服务的压力

使用Actuator暴露Hystrix监控日志

Hystrix利用Actuator来暴露自己的监控日志
添加Actuator:
Actuator时Springboot提供的一个项目指标工具

  • 健康状态
  • spring容器 中所有对象
  • springmvc映射的所有路径
  • java虚拟机堆内存镜像

Actuator依赖:

暴露监控日志:

Hystrix数据监控-Hystrix Dashboard

1.新建spring模块:sp07-hystrix-dashboard
2.添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud1</artifactId>
        <groupId>cn.tedu</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>sp07-hystrix-bashboard</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sp07-hystrix-bashboard</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
    </dependencies>
</project>

3.配置文件

server:
  port: 4001
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost

4.启动类加注解@EnableHystrixDashboard
5.访问: http://localhost:4001/hystrix
然后在里边输入http://localhost:3001/actuator/hystrix.stream测试

举报

相关推荐

0 条评论