精华内容
下载资源
问答
  • 定义接口 即远程调用的功能(Feign继承的ribbon的RestTemplate远程调用) 接口的实现类(Feign继承的hystrix的回调 错误降级) ItemFeignServiceFB 获取商品列表的降级方法,模拟使用缓存数据 UserFei

    idea按两下shift 全局搜索

    上午 继续完善feign

    order service 调用商品库存服务和用户服务

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    自我实现

    加上对应依赖

    订单模块
    在这里插入图片描述
    主启动类
    在这里插入图片描述
    配置完成

    额外的点 actuator和dashboard相辅相成的解释

    在这里插入图片描述

    定义接口 即远程调用的功能(Feign继承的ribbon的RestTemplate远程调用)

    在这里插入图片描述
    在这里插入图片描述

    接口的实现类(Feign继承的hystrix的回调 错误降级)

    在这里插入图片描述

    ItemFeignServiceFB 获取商品列表的降级方法,模拟使用缓存数据

    在这里插入图片描述
    在这里插入图片描述

    UserFeignServiceFB 获取用户信息的降级方法,模拟使用缓存数据

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    远程调用实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    自我实现在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    复制运行
    在这里插入图片描述
    在这里插入图片描述

    页面效果

    首先 定死的数据
    在这里插入图片描述
    item倒是随意 无论id为多少 都是定死
    在这里插入图片描述

    在这里插入图片描述

    可能性1:设定了百分之50 的成功 假装查到数据库数据

    在这里插入图片描述
    在这里插入图片描述

    可能性2:百分之50得缓存

    在这里插入图片描述

    可能性3:还有错误得情况 因为item模块设置了90的不成功率

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    浏览器自动去请求这个图标

    完美实现

    继续

    actuator 不通过仪表盘监听的话 一大堆ping的乱值

    http://localhost:8201/actuator/hystrix.stream
    http://localhost:8202/actuator/hystrix.stream
    在这里插入图片描述

    开启仪表盘 dashboard

    在这里插入图片描述

    在这里插入图片描述
    上面只是对单台的监控

    Turbine

    对集群服务器 多台的监控 turbine

    在这里插入图片描述

    hystrix dashboard 一次只能监控一个服务实例,使用 turbine 可以汇集监控信息,将聚合后的信息提供给 hystrix dashboard 来集中展示和监控

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    自我实现

    依赖
    在这里插入图片描述
    配置文件
    在这里插入图片描述
    在这里插入图片描述

    主启动类 添加注解

    在这里插入图片描述

    页面实现

    turbine 监控路径
    http://localhost:5001/turbine.stream

    在 hystrix dashboard 中填入turbine 监控路径,开启监控
    http://localhost:4001/hystrix

    turbine聚合了order-service两台服务器的hystrix监控信息
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    下午
    在这里插入图片描述

    在这里插入图片描述
    还是有监控数据 都会有监控信息

    在这里插入图片描述
    rabbitMQ

    ack模式 false 关闭了自动确认 要收到发送凭证回队列在这里插入图片描述

    监控是不是必须的服务?

    和用户 提供者可能是异步
    在这里插入图片描述
    服务器在缓存的话 在本地内存中 可能会崩溃 崩溃后 数据都会丢失
    在这里插入图片描述

    redis持久化

    rdb和aof

    回到rabbitMQ 消息持久化

    在这里插入图片描述

    在这里插入图片描述

    1.队列持久化

    在这里插入图片描述
    在这里插入图片描述
    默认来说 不能修改

    策略 新建一个队列

    调整 生产者和消费者都改为新队列
    在这里插入图片描述
    在这里插入图片描述

    消息也设置为持久化

    在这里插入图片描述
    在这里插入图片描述
    会存储到磁盘

    涛哥测试在这里插入图片描述

    重启rabbitMQ服务器

    会重新投递
    在这里插入图片描述
    Unacked 未确认 persistent 持久的

    自我实现 测试

    消费者

    在这里插入图片描述
    消费者接收的数据
    在这里插入图片描述

    提供者

    在这里插入图片描述
    在这里插入图片描述
    已创建一个新队列(持久化的)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    17.03前 晚上看多一遍 是怎么恢复的 实践

    发布模式

    在这里插入图片描述
    在这里插入图片描述

    Exchanges 交换机 理解 类似nginx反向代理

    RabbitMQ消息传递模型的核心思想是,生产者永远不会将任何消息直接发送到队列实际上,通常生产者甚至不知道消息是否会被传递到任何队列。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    新建一个生产者

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    自定义服务器id
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    没人接收 自动删除

    和前两种对比在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    消费者
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    总结 最简单的理解

    在这里插入图片描述
    邮局 如下图
    在这里插入图片描述
    在这里插入图片描述

    自我实现 发布模式 交换机

    提供者

    package m3_publishsubscribe;
    
    import com.rabbitmq.client.BuiltinExchangeType;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.ConnectionFactory;
    
    import java.util.Scanner;
    
    public class Producer {
        public static void main(String[] args) throws Exception {
            ConnectionFactory f = new ConnectionFactory();
            f.setHost("192.168.64.140"); //www.wht6.cn
            f.setPort(5672); //默认端口可以省略
            f.setUsername("admin");
            f.setPassword("admin");
            // f.setVirtualHost("/xxxx");
    
            Channel c = f.newConnection().createChannel();
    
            // 定义 fanout 类型交换机:logs
            //c.exchangeDeclare("logs", "fanout");
            c.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
    
            // 向交换机发送消息
            while (true) {
                System.out.println("输入消息: ");
                String msg = new Scanner(System.in).nextLine();
                c.basicPublish(
                        "logs",
                        "",
                        null,
                        msg.getBytes());
            }
    
        }
    }
    
    

    消费者

    package m3_publishsubscribe;
    
    import com.rabbitmq.client.*;
    
    import java.io.IOException;
    import java.util.UUID;
    
    public class Consumer {
        public static void main(String[] args) throws Exception {
            ConnectionFactory f = new ConnectionFactory();
            f.setHost("192.168.64.140"); //www.wht6.cn
            f.setPort(5672); //默认端口可以省略
            f.setUsername("admin");
            f.setPassword("admin");
            // f.setVirtualHost("/xxxx");
    
            Channel c = f.newConnection().createChannel();
    
            // 1.定义随机队列 2.定义交换机 3.绑定
            // 随机命名,非持久,独占,自动删除
            String queue = UUID.randomUUID().toString();
            c.queueDeclare(
                    queue,
                    false,
                    true,
                    true,
                    null);
            c.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
            //第三个参数对fanout交换机无效
            c.queueBind(queue, "logs", "");
    
            DeliverCallback deliverCallback = new DeliverCallback() {
                @Override
                public void handle(String consumerTag, Delivery message) throws IOException {
                    String msg = new String(message.getBody());
                    System.out.println("收到: "+msg);
                }
            };
            CancelCallback cancelCallback = new CancelCallback() {
                @Override
                public void handle(String consumerTag) throws IOException {
                }
            };
            // 正常地消费数据
            c.basicConsume(
                    queue,
                    true,
                    deliverCallback,
                    cancelCallback);
    
        }
    }
    
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    路由模式

    在这里插入图片描述
    在这里插入图片描述
    通过关系词的匹配 路由消息
    在这里插入图片描述

    涛哥实现

    生产者

    在这里插入图片描述
    在这里插入图片描述
    改一下

    消费者

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    正则表达式 \表示空白字符的匹配
    在这里插入图片描述
    关联
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    https://www.runoob.com/regexp/regexp-metachar.html

    自我实现

    在这里插入图片描述
    复制一个 调成并行
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 在目前微服务体系下,我们服务url访问有两种,一种是从网关(gateway,zuul)路由进来,还有一种就是通过feign接口内部调用,那么结合spring-security就存在以下几种场景: 1.外部请求从gateway访问,需要鉴权(任何CURD...

         在目前微服务的体系下,我们服务url的访问有两种,一种是从网关(gateway,zuul)路由进来,还有一种就是通过feign接口内部调用,那么结合spring-security就存在以下几种场景:

        1.外部请求从gateway访问,需要鉴权(任何CURD的操作).这是目前最常见的方式,用户正常登录提供token访问接口,我们不再需要做其他处理.

        2.外部请求从gateway访问,不需要鉴权(eg:刷新验证码,短信验证码获取...). 此时我们需要将放行的接口加入到ignore-urls配置里,可以不需要做鉴权处理

        3.内部服务使用feign调用,不需要鉴权(根据id查询信息...). 也需要将url加入到ignore-urls中,配置放行,但是这样一来,不仅仅是这个服务可以访问这个接口,其他服务也可以,甚至是外部请求也可以访问到,这样就会有很大的安全问题.

     

        鉴于上述第三种情况,我们配置了ignore-url和Feign,此时该接口不需要鉴权,服务内部通过Feign访问,服务外部通过url也可以访问,所以我们需要加入一种@RequestHeader(CommonConstants.WHERE)的处理方式。即在接口方法中,对头部进行判断,只有请求带上相应的Header参数时,才允许通过访问,否则抛出异常。那这时候其实我们在外网通过Gateway访问的时候,也可以手动带上这个Header参数,来达到这个目的。所以我们便在Gateway中设置了一个GlobalFilter过滤器,对来自外网通过Gateway手动拼接的参数进行过滤与清洗,具体代码见com.lfs.gateway.filter.LfsRequestGlobalFilter:

       

    @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 1. 请求头中where 参数删除
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .headers(httpHeaders -> httpHeaders.remove(CommonConstants.WHERE)).build();
    
            // 2. 重写StripPrefix
            addOriginalRequestUrl(exchange, request.getURI());
            String rawPath = request.getURI().getRawPath();
            String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")).skip(1L)
                    .collect(Collectors.joining("/"));
            ServerHttpRequest newRequest = request.mutate().path(newPath).build();
            exchange.getAttributes().put(REQUEST_URL_ATTR, newRequest.getURI());
            return chain.filter(exchange.mutate().request(newRequest.mutate().build()).build());
        }

    下面是Inner注解的代码:

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Inner {
       /**
        * 是否AOP统一处理(可以理解为是否仅允许Feign之间调用)
        *
        * @return false, true
        */
       boolean value() default true;
    
       /**
        * 需要特殊判空的字段(预留)
        *
        * @return {}
        */
       String[] field() default {};
    }

    接下来是框架中加入环绕切面:

    @Slf4j
    @Aspect
    @AllArgsConstructor
    public class SecurityInnerAspect {
       private final HttpServletRequest request;
    
       @SneakyThrows
       @Around("@annotation(inner)")
       public Object around(ProceedingJoinPoint point, Inner inner) {
          String header = request.getHeader(CommonConstans.WHERE);
          if (inner.value() && !StrUtil.equals(CommonConstans.IN, header)) {
             log.warn("访问接口 {} 没有权限", point.getSignature().getName());
             throw new BizException("Access is denied");
          }
          return point.proceed();
       }
    }

    合理的使用@Inner注解

     

       在我们的代码中,可以直接使用Inner注解的,下面结合Feign做一个简单的示例,比如获取用户信息这个接口:

     

    在接口上使用@Inner注解,使得url无需鉴权
        /**
         * 获取指定用户全部信息
         *
         * @return 用户信息
         */
        @Inner
        @GetMapping("/info/{userId}")
        public Result getUserInfo(@PathVariable Integer userId) {
           SysUser user = userService.getOne(Wrappers.<SysUser>query()
                 .lambda().eq(SysUser::getUserId, userId));
           if (user == null) {
              return Result.fail(null, String.format("用户信息为空 %s", userId));
           }
           return Result.success(userService.findUserInfo(user));
        }
    1. 编写Feign接口
    @FeignClient(contextId = "userService", value = CommonConstans.USER_SERVER)
    public interface UserService {
        /**
         * 通过用户id查询用户、角色信息
         *
         * @param 用户id
         * @param from     调用标志
         * @return R
         */
        @GetMapping("/user/info/{userId}")
        R<UserInfo> getUserInfo(@PathVariable("userId") Integer userId
              , @RequestHeader(CommonConstants.WHERE) String where);
    }
    1. Feign-Client中调用接口,带上CommonConstants.IN参数为内部识别
    /**
         * 用户密码登录
         *
         * @param userId用户名
         * @return
         * @throws UsernameNotFoundException
         */
        @Override
        @SneakyThrows
        public UserDetails loadUserByUserId(Integer userId) {
           R<UserInfo> result = userService.getUserInfo(userId, CommonConstants.IN);
           UserDetails userDetails = getUserDetails(result);
           cache.put(userId, userDetails);
           return userDetails;
        }

     

    现在"/info/{userId}" 这个uri从网关外部我们访问是报错的(一般来说服务都是走网关暴露接口),而Feign内部带上参数是可以正常访问的.

    •  
    展开全文
  • Spring cloud中当调用第三接口时候,为防止超时一直等待,我们一般用断路由的方式来进行超时返回,我一般用Spring Cloud Hystrix。在调用第三方地方进行fallback进行声明,然后重新fallback函数,配置超时时间,...

    Spring cloud中当调用第三接口的时候,为防止超时一直等待,我们一般用断路由的方式来进行超时返回,我一般用Spring Cloud Hystrix。在调用第三方的地方进行fallback进行声明,然后重新fallback函数,配置超时时间,在超时时间内容没有返回或者参数错误就进人到fallback里面进行处理。具体的做法,网上一大堆,可自行百度。

    然后第三方接口,在参数错误的时候,也是按400返回,尤其是json里面的数据key对应的value的合法性。而我们出错的时候想把第三参数的错误信息返回,这样就能很明确知道哪错了,而不是认为是超时,下面进入正题:

    1.调用第三方的方法

    fallbackFactory中调用自己重写的fallback,熔断时会自动调用。

    2.fallback函数返回值的组合

    自己重写的熔断函数中,重新create函数,其中throwable 会记录捕获的所有异常,我们通过getMessage可得到我们的信息,具体可以参考FallbackFactory接口的实现。

    3.返回值

    把fallback函数的返回值反倒返回值的msg中返回,这样调用接口的时候就可以得到第三方返回的错误信息,进行调整了。

     

    展开全文
  • 简单看图 上图显示了SpringCloud常见组件在日常开发中...1.服务A中要调用服务B服务,Feign依赖Ribbon做负载均衡. 2.Ribbon通过EurakeClient去EurakeServer获取服务列表 3.EurakeClient去EurakeServer获取服务列表

    简单看图

    SpingCloud组件关系

    上图显示了SpringCloud常见组件在日常开发中的使用情况,下面按照流程介绍:
    • gateway在接到来自外部的请求的时候,会首先进行处理,gateway能做的事情很多,权限管理,负载均衡(通过rubbion),动态路由等。
    • 0.gateway将请求转发给对应的服务A,
    • 1.服务A中要调用服务B的服务,Feign依赖Ribbon做负载均衡.
    • 2.Ribbon通过EurakeClient去EurakeServer获取服务列表
    • 3.EurakeClient去EurakeServer获取服务列表
    • 4.EurakeServer返回服务列表
    • 5.Ribbon获得B服务的所有实例信息,根据算法策略选取其中一个服务的实例返给Feign
    • 6.Ribbon返回选中的B服务的实例
    • 7.Feign像Ribbon返回的B服务的实例发起请求
    • 8.Hystrix收集请求的信息
    • 9.Hystrix根据服务B响应的信息,对比设置的服务熔断和降级策略,符合则执行对服务进行熔断和降级
    • 10.将返回信息返回给Feign
    • 11.待整个服务A的流程处理完毕返回响应内容给网关,最终返回给用户
    展开全文
  • Ribbon提供了**轮询、随机两种负载均衡算法(默认是轮询)**可以实现从地址列表中使用负载均衡算法获取地址进行服务调用。 2.步骤 像双十一时候,订单秒杀,一个服务访问量会特别大,所以就需要多个来执行同一个
  • 主要解决了服务调用不通,而一直阻塞从而导致服务连续崩溃问题,feign内部就有集成了熔断器实现起来非常简单,而Zuul网关依赖里面也包括了Hystrix依赖, 那么就可以来进行实现当网关转发请求时候,一直连接不通,或者长...
  • Spring Cloud Eureka REST 接口

    万次阅读 2017-12-14 09:44:21
    Eureka 作为注册中心,其本质是存储了每个客户端的注册信息,Ribbon在转发的时候会获取注册中心的服务列表,然后根据对应的路由规则来选择一个服务给Feign来进行调用。如果我们不是Spring Cloud技术选型,也想用...
  • Eureka Client:负责将这个服务...ribbon:负载均衡,获取服务信息,feign调用服务。feign:调用服务。Hystrix是隔离、熔断以及降级一个框架。zuul:网路路由。 具体内容参考下面文章讲很透彻。 https://blog.cs...
  • 在我们前面博客中讲到,当服务A需要调用服务B时候,只需要从Eureka中获取B服务注册实例,然后使用Feign调用B服务,使用Ribbon来实现负载均衡,但是,当我们同时向客户端暴漏多个服务时候,客户端怎么...
  • Eureka 作为注册中心,其本质是存储了每个客户端的注册信息,Ribbon 在转发的时候会获取注册中心的服务列表,然后根据对应的路由规则来选择一个服务给 Feign 来进行调用。如果我们不是 Spring Cloud
  • Eureka REST APIEureka 作为注册中心,其本质是存储了每个客户端的注册信息,Ribbon 在转发的时候会获取注册中心的服务列表,然后根据对应的路由规则来选择一个服务给 Feign 来进行调用。如果我们不是 Spring Cloud ...
  • Eureka 作为注册中心,其本质是存储了每个客户端的注册信息,Ribbon 在转发的时候会获取注册中心的服务列表,然后根据对应的路由规则来选择一个服务给 Feign 来进行调用。如果我们不是 Spring Cloud 技术选型,也想...
  • 通过与Zuul来进行路由的映射,从而可以做到服务的获取,然后可以使用Ribbon,Feign对服务进行消费,以及对Config Server间接性调用。 你是否想要在非jvm语言中利用(间接性使用)Eureka,Ribbon以及Config ...
  • springCloud

    2018-08-09 16:54:33
    消息代理是一个中间件产品,它的核心是一个消息的路由程序,用来实现接收和分发消息,并根据设定好的消息处理流来转发给正确的应用。它包括独立的通信和消息传递协议,能够实现组织内部和组织间的网络通信。设计代理...
  • spingCloud 技术组成

    2020-12-04 12:03:16
    重点: 基于 Spring Boot 云服务、分布式框架集合(众多) 核心功能: 分布式/版本化配置 ...路由 服务和服务之间的调用 ...请求统一通过 API 网关(Zuul)来访问内部服务。... Turbine 监控服务间的调用和熔断...
  • 分布式/版本化配置服务注册和发现路由服务和服务之间的调用负载均衡断路器分布式消息传递 通过这张图,我们来了解一下各组件配置使用运行流程: 1、请求统一通过API网关(Zuul)来访问内部服务.2、网关接收到...
  • Spring Cloud Feign的两种使用姿势 Spring Cloud Eureka Server高可用之:在线扩容 Eureka Server 开启Spring Security Basic认证 Eureka Server启用 https服务指北 Docker容器/集群 利用ELK搭建Docker容器化...
  • Spring Cloud中如何优雅使用Feign调用接口:http://cxytiandi.com/blog/detail/12189 Spring Cloud Feign fallback错误解决:http://cxytiandi.com/blog/detail/12368 Spring Cloud Feign 启动Unsatisfied...
  • React学习笔记_利用cors实现ajax跨域_Tomcat 获取跨域Authorization React学习笔记_ReactRedux应用使用AsyncAwait React学习笔记_动态注入reducer React学习笔记_export和import总结 React学习笔记_安装...
  • Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue 前后端分离后台管理系统,项目采用分模块开发方式, 权限控制采用 RBAC,支持数据字典与数据权限管理,支持一键生成前后端代码,支持动态路由。...

空空如也

空空如也

1 2
收藏数 24
精华内容 9
关键字:

获取feign调用的路由