乐优商城day03

所有代码发布在 [https://github.com/hades0525/leyou]

 

Day03

2019118

11:45

Springcloud

 

Hystrix(一种保护机制/熔断器)

  1. Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
    1. 雪崩问题:微服务中调用关系复杂,如果一个调用异常,请求阻塞,导致其他服务都不可用,形式雪崩效应。
    2. Hystrix解决雪崩问题两个手段:
      1. 线程隔离
      2. 服务熔断

 

线程隔离,服务降级(消费者方)

    1. 把各个线程隔离开,线程池满了后,会优先保证核心服务,非核心服务不可用或弱可用
    2. 请求故障时,不会阻塞或无线等待,至少返回一个执行结果
    3. 触发服务降级的情况
      1. 线程池满
      2. 请求超时

使用:

    1. 引入依赖

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

</dependency>

    1. 启动类上添加注解 @@EnableCircuitBreaker
      1. 后期注解过多,使用组合注解@springCloudApplication

代替3个注解

@EnableCircuitBreaker

@EnableDiscoveryClient

@SpringBootApplication

    1. 编写降级逻辑
      1. 降级逻辑方法必须和正常逻辑方法参数和返回值一致

@GetMapping("{id}")

@HystrixCommand(fallbackMethod="queryByIdFallBcak")

Public String queryById(@PathVariable("id")Longid){

Stringurl="http://user-service/user/"+id;

Stringuser=restTemplate.getForObject(url,String.class);

returnuser;

}

Public String queryByIdFallBcak(Longid){

return"对不起,服务器太拥挤";

}

    1. 设置通用的fallback

在consumer调用类上@DefaultProperties(defaultFallback="defalutFallBcak")

 

Public String defalutFallBcak(){

return"对不起,服务器太拥挤";

}

在启用的方法上添加@Hystrix即可

    1. 自定义超时时长
      1. 配置一个方法的

@HystrixCommand(commandProperties={

@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")

})

    1. 全局配置

hystrix:

command:

default:

isolation:

thread:

timeoutInMilliseconds:3000

 

    1. 针对一个服务或方法

hystrix:

command:

服务名/方法:

isolation:

thread:

timeoutInMilliseconds:3000

 

 

服务熔断(Circuit Breaker):

  1. 服务降级的等待时长过长,降低了并发效率,所以用熔断器。
  2. 熔断器3个状态

 

 

 

@HystrixCommand(commandProperties={

@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),

@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),

@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="60"),

})

 

一般要自定义控制超时的时长,不修改熔断的设置。

 

Feign:

    1. 作用:把远程请求隐藏,伪装成和contrller一样
      1. 省略代码,伪装成controller

Stringurl="http://user-service/user/"+id;

Stringuser=restTemplate.getForObject(url,String.class);

    1. 引入依赖

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

    1. 启动类注解 @EnableFeignClients
    2. 编写接口

@FeignClient("user-service")

public interface UserClient{

@GetMapping("user/{id}")

User queryById(@PathVariable("id") Long id);

}

    1. 直接调用

@Autowired

private UserClient userClient;

 

@GetMapping("{id}")

public User queryById(@PathVariable("id")Longid){

return userClient.queryById(id);

}   

    1. feign已经实现了ribbon和hystrix
      1. feign配置ribbon

user-service:

  ribbon:

    ConnectTimeout: 250 # 连接超时时间(ms)

    ReadTimeout: 1000 # 通信超时时间(ms)

    OkToRetryOnAllOperations: true # 是否对所有操作重试

    MaxAutoRetriesNextServer: 1 # 同一服务不同实例的重试次数

    MaxAutoRetries: 1 # 同一实例的重试次数

    1. feign配置hystrix(默认关闭)
      1. 开启熔断

feign:

  hystrix:

    enabled: true # 开启Feign的熔断功能

    1. 定义一个类实现接口UserClient

@Component

public class UserClientFallback implements UserClient{

@Override

public UserqueryById(Longid){

User user = new User();

user.setUser_name("未知用户");

return user;

}

}

    1. 接口上注解添加熔断类

@FeignClient(value="user-service",fallback=UserClientFallback.class)

 

zuul:微服务网关

服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

使用:新建一个网关module

    1. 引入依赖

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-zuul</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

    1. 启动类

@EnableZuulProxy

@SpringBootApplication

publicclassGatewayApplication{

publicstaticvoidmain(String[]args){

SpringApplication.run(GatewayApplication.class);

}

}

    1. 配置application.yml

server:

  port: 10010

spring:

  application:

    name: gateway

eureka:  #添加eureka配置

  client:

    service-url:

      defaultZone: http://127.0.0.1:10087/eureka

zuul: #设置映射配置

  routes:

    user-service: /user/** #访问url:http://127.0.0.1:10010/user/user/1

  ignored-services: #设置不能访问的服务

    - consumer-service

 

    1. 过滤器(zuul的核心就是一系列的过滤器)
      1. ZuulFilter是过滤器的顶级父类,4个最重要的方法

public abstract ZuulFilter implements IZuulFilter{

 

    abstract public String filterType();//过滤器类型

 

    abstract public int filterOrder();//过滤器顺序(优先级)

   

    boolean shouldFilter();// 是否需要执行过滤器

 

    Object run() throws ZuulException;// 具体的业务逻辑

}

    1. 过滤器类型
      • pre:请求在被路由之前执行
      • routing:在路由请求时调用
      • post:在routing和errror过滤器之后调用
      • error:处理请求时发生错误调用
    • 自定义过滤器

public class LoginFilter extends ZuulFilter {

    @Override

    public String filterType() {

        return FilterConstants.PRE_TYPE;

    }

    @Override

    public int filterOrder() {

        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;

    }

    @Override

    public boolean shouldFilter() {

        return true;

    }

    @Override

    public Object run() throws ZuulException {

        //获取请求上下文

        RequestContext ctx = RequestContext.getCurrentContext();

        //获取request

        HttpServletRequest request = ctx.getRequest();

        //获取请求参数

        String token = request.getParameter("access-token");

        //判断是否存在

        if(StringUtils.isBlank(token)){

            //不存在,未登录,则拦截

            ctx.setSendZuulResponse(false);

            //状态码403,禁用

            ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());

        }

        return null;

    }

}

 

 

    1. 负载均衡和熔断

ribbon真正的默认超时时长是原有时长(连接时长+通信时长)的2倍

hystrix超时时长应该大于ribbon的真正超长时长

    1. Zull的高可用
      1. 启动多个zuul服务,注册到eureka形式集群,内部访问自动负载均衡
      2. 外部访问时,无法 通过erreka实现负载均衡,通过使用其他网关,如nginx对zuul进行代理

 

其他的springcloud组件

  1. spring-cloud-config:统一配置中心。配置统一放到git。拉取配置列表
  2. spring-cloud-bus:消息总线(activitiMQ或kafaka实现)。
    1. 当git有新的提交时,会通过调用配置中心定义好的hook(接口)拉取git上的配置,通过消息总线,向所有微服务推送配置更新的通知,微服务自动拉取最新的配置,并且不重启,自动生效。
  3. spring-cloud-hystrix-dashboard:容错统计,图形化界面
  4. spring-cloud-sleuth:链路追踪(结合zipkin),体现各个微服务之间的调用关系

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自己做的乐优商城的XMIND文件,学习分享下。乐优商城 搭建父工程 pom.xml 添加依赖 springCloud mybatis启动器 通用Mapper启动器 mysql驱动 分页助手启动器 FastDFS客户端 其他配置 构建设置 环境设置 EurekaServer注册中心 添加的依赖 启动类 application.yml 创建Zuul网关 依赖 启动类 application.yml 创建商品微服务 ly-item-interface:主要是对外暴露的API接口及相关实体类 ly-item-service:所有业务逻辑及内部使用接口 创建父工程ly-item ly-item-interface ly-item-service 依赖 启动器 application.yml 添加商品微服务的路由规则 通用工具模块Common utils CookieUtils IdWorker JsonUtils NumberUtils 依赖 通用异常处理 测试结构 pojo service @Service web @RestController @RequestMapping @Autowired @PostMapping 引入Common依赖 Common advice 拦截异常、 CommonExceptionHandler ResponseEntity @ControllerAdvice @ExceptionHandler enums 异常的枚举 、ExceptionEnum exception 自定义异常、LyException 接口RuntimeException @Getter @NoArgsConstructor @AllArgsConstructor vo 异常结果处理对象、ExceptionResult @Data 构造方法ExceptionResult ly-item-service CategoryQuery 分类查询 实体类 @Table(name="tb_category") 声明此对象映射到数据库的数据表,通过它可以为实体指定表(talbe) @Data 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法 @Id & @GeneratedValue(strategy= GenerationType.IDENTITY) 自动增长,适用于支持自增字段的数据库 mapper Mapper IdListMapper 根据id操作数据库 @RequestMapping("category") Controller @RestController @Controller 处理HTTP请求 @ResponseBody 返回 json 数据 @GetMapping("list") ResponseEntity @ResponseBody可以直接返回Json结果 不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus service @Service 自动注册到Spring容器,不需要再在applicationContext.xml文件定义bean了 @Autowired 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 select select * from category c where c.pid = #{pid} CollectionUtils.isnotblank 判断集合是否为空 测试 可以利用url直接查询数据库,能否访问得到数据 报错 启动类 没有扫描到 @MapperScan("com.leyou.item.mapper") ,目录结构关系 访问网页报错 CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 跨域问题 浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。因此:跨域问题 是针对ajax的一种限制。 解决跨域问题的方案 CORS 规范化的跨域请求解决方案,安全可靠 什么是cors 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。 原理 简单请求 当浏览器发现发现的ajax请求是简单请求时,会在请求头中携带一个字段:Origin 如果服务器允许跨域,需要在返回的响应头中携带下面信息 Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*,代表任意 Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true 实现非常简单 gateway网关中编写一个配置类 GlobalCorsConfig 添加CORS配置信息 允许的域,不要写*,否则cookie就无法使用了 是否发送Cookie信息 允许的请求方式 允许的头信息 有效时长 添加映射路径,我们拦截一切请求 返回新的CorsFilter 提交方式 GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源 BUG 分类不能打开,当添加后却能打开。 修改一天的BUG 最后发现是实体类里属性大小写的问题引起。 注意 Bule_bird 就必须写成 BlueBird Brand 查询 实体类 PageResult 响应结果 分页结果一般至少需要两个数据 总条数 total 当前页数据 items 有些还需要总页数 总页数 totalPage Controller @RequestParam(value = "page",defaultValue = "1") Integer page GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上 defaultValue 默认值 required 默认值为true , 当为false时 这个注解可以不传这个参数 null || .size()==0 ResponseEntity(HttpStatus.NOT_FOUND) 返回404没找到 ResponseEntity.ok 返回ok状态 service 开始分页 通用分页拦截器 PageHelper.startPage(page,row); 过滤 Example查询 Example example = new Example(Brand.class); mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分 xxxExample example = new xxxExample(); Criteria criteria = new Example().createCriteria(); StringUtils.isNotBlank isNotBlank(str) 等价于 str != null && str.length > 0 && str.trim().length > 0 str.trim() 去掉字符串头尾的空格 测试 报错500 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'idASC' in 'order clause' 错误:(desc ? "DESC" : "ASC"); 正确:(desc ? " DESC" : " ASC"); 字符串空格问题 新增 Controller (Brand brand,@RequestParam("cids") List cids) ResponseEntity 无返回值 new ResponseEntity(HttpStatus.CREATED); 201成功 service @Transactional 自动纳入 Spring 的事务管理 使用默认配置,抛出异常之后,事务会自动回滚,数据不会插入到数据库。 setId(null) insert(brand) 新增中间表 mapper @Insert (#{cid},#{bid}) @Param 表示给参数命名,名称就是括号中的内容 name 命名为aa,然后sql语句....where s_name= #{aa} 中就可以根据aa得到参数值 修改 回显 Controller @PathVariable("bid") 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。 select * from tb_category where id in (select category_id from tb_category_brand where brand_id = #{bid}) 测试 报错500 空指针异常 调用Service时候 忘记@Autowired 保存 VO视图对象 @NoArgsConstructor 生成一个无参数的构造方法 @AllArgsConstructor 会生成一个包含所有变量 Controller @PutMapping 添加信息,倾向于用@PostMapping,如果是更新信息,倾向于用@PutMapping。两者差别不是很明显 return ResponseEntity.ok().build(); 无返回值 service 根据id修改 先删除后新增 删除(前端有问题,待完善) spec Group 品牌分类id查询 实体类 @Transient 指定该属性或字段不是永久的。 它用于注释实体类,映射超类或可嵌入类的属性或字段。 @Column(name = "'numeric'") 用来标识实体类中属性与数据表中字段的对应关系 name 定义了被标注字段在数据库表中所对应字段的名称; mapper service Controller 测试 报错500 实体类@table路径写错 新增 Controller @RequestBody 常用其来处理application/json类型 子主题 2 将请求体中的JSON字符串绑定到相应的bean上 修改 Controller @PutMapping service updateByPrimaryKey 删除 Controller @DeleteMapping @PathVariable Param 规格组id查询规格 url:params?gid=14 @GetMapping("params") Controller @RequestParam 新增 @PostMapping("param") @RequestBody ResponseEntity.status(HttpStatus.CREATED).build(); 修改 @RequestBody 删除 @PathVariable 分支主题 3 遇到的问题 pom.xml 文件未下载完整,删掉后重新下载 能存在重复文件,IDEA不能确定文件路径,需要搜索删掉多余的 Param 删除 小问题:数据库删除后页面没有立即显示 Brand 删除(前端有问题,待完善)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值