精华内容
下载资源
问答
  • RocketMq什么时候会重复消费

    千次阅读 2020-05-24 19:13:32
    而cluster集群模式下,负载均衡策略(RebalanceImpl)将多个ConsumerQueue平均分配给ConsumerGroup下的消费者实例(默认平均分配策略),不会出现同一个消费者组中有两个或以上的consumer实例消费同一个队列。...

    1.消费者负载均衡

    当我们的Consumer定义为BroadCast广播模式的话,每个ConsumerGroup下的consumer都会获得全量消息。此时拉取消息时不同的节点会得到相同的消息。

    而cluster集群模式下,负载均衡策略(RebalanceImpl)会将多个ConsumerQueue平均分配给ConsumerGroup下的消费者实例(默认平均分配策略),不会出现同一个消费者组中有两个或以上的consumer实例消费同一个队列。比如:
    consumer1:queue1,queue2
    consumer2:queue3,queue4
    这样同一个consumerGroup下不同的consumer消费各自的队列,就减少了重复拉取的危险

    2.使用DefaultMqPullConsumer

    Pull模式的Consumer,拉取完消息后的后续处理都需要业务方进行实现,
    同时消费完了,也没有一个ACK去告诉Broker这些消息已经被消费了。
    这是如果两个节点同时拉取就重复掉了。
    这种情况比较少。生成环境中一般使用DefaultMqPushConsumer。因为DefaultMqPushConsumer编码难度小,是基于DefaultMqPullConsumer的一层封装。而且根据消费的结果返回一个ACK消息。自身的实现上不会消费已经消费过的消息

    3.消费失败后返回RECONSUME_LATER进行容错

    一般情况下如果出现异常后,对异常处理的结果是过段时间重新消费一次
    比如

      defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() {
                int a=1;
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                    System.out.println(msgs.size());
                    try {
                        System.out.println(new String(msgs.get(0).getBody(),"UTF-8"));
                    } catch (UnsupportedEncodingException e) {
                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });
            defaultMQPushConsumer.start();
    

    异常捕获时返回的ACK为RECONSUME_LATER,则会在一段时间后进行重试。

    4.Producer发送时,出现网络问题

    如果producer发送了消息,此时broker已经同步刷盘或异步刷盘成功了。但是返回ACK时出现网络问题。此时producer会进行重发,这是broker上就会出现两条相同的消息

    源码如下:
    在这里插入图片描述

    5.Consumer节点重启

    Consumer所在节点,消费完后还未来得及返回处理结果,此时服务宕机或重启。此时已经消费1次。
    随后运维重新启动节点,会再次消费一次。总共出现两次消费重复。

    6.Consumer消费时间超时

    如果Consumer消费完后迟迟没有返回结果,此时会触发一次重新消费
    经过测试,最多也只重新消费1次

    总结:
    生产环境下情况复杂,mq是无法避免消息重复的。通过业务上进行幂等性校验。比如通过关系型数据库的主键进行幂等性校验。或者短期业务使用redis实现的布隆过滤器,bitmap进行短期校验。

    展开全文
  • 于是,各种排查,为什么会有多次重复执行相同的sql查询,这岂不是很影响性能。于是有了下面的排查过程。 二、发现问题,截图如下: 三、排查过程 (过程1):肯定是先从shiro的配置文件逐个排查过了,没有任何发现...

    前言:此次排查的过程,主要是利用debug模式下,深入源码打断点才发现问题所在。

    一、问题描述:

    练习shiro认证授权,发现授权方法中相关的sql语句多次重复执行了。于是,各种排查,为什么会有多次重复执行相同的sql查询,这岂不是很影响性能。于是有了下面的排查过程。

    二、发现问题,截图如下:

    在这里插入图片描述

    三、排查过程

    (过程1):肯定是先从shiro的配置文件逐个排查过了,没有任何发现,还是解决不了问题。

    (过程2):既然是多次sql语句执行,那考虑到是某个方法重复调用了。于是定位到了下边的这个方法。
    在这里插入图片描述
    a)debug模式启动,断点来到上边的Set<String> roleNames = roleDAO.queryRoleNamesByUsername(username);

    b)于是从逆向思维出发,是谁调用了protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)方法。

    借助调试工具,Step Out (Shift + F8):步出,从步入的方法内退出到方法调用处,此时方法已执行完毕,只是还没有完成赋值。

    调式工具
    c)借助调式工具,Step Out看看是谁调用了doGetAuthorizationInfo()方法。
    来到AuthorizingRealm类的isPermitted(PrincipalCollection principals, String permission)方法。
    在这里插入图片描述
    d)继续Step Out,来到同类下的isPermitted(PrincipalCollection principals, Permission permission);
    在这里插入图片描述
    e)继续Step Out,来到同类下的info = this.doGetAuthorizationInfo(principals);
    在这里插入图片描述
    e)继续Step Out多次…,来到了一个循环do{}while()循环,如下。
    在这里插入图片描述
    f)到了这一步,多少看出一点猫腻了,这个permission:“sys:c:delete”,就是来自数据库的权限内容。

    g)于是好奇重复执行了多少次该sql的执行。
    doGetAuthorizationInfo(PrincipalCollection principalCollection)方法体内定义一个变量,看看到底执行了多少次。
    定义的变量如下:
    在这里插入图片描述
    执行结果如下:
    在这里插入图片描述
    发现都是次数1,这就奇怪了,说明都是一个新的对象调用该方法。
    h)接着数了下,一共执行了11次,然后回到数据库,查看有没有什么记录是11次的。发现还是没有,到这里就又觉得没思绪了。

    i)最后,想到了前端是用的thymeleaf模板中用到了shiro的授权标签。
    在这里插入图片描述
    数了下,恰好是11个,这就跟控制台打印的sql方法执行的个数相符合了。

    j)为了确认下,是由于前端这个11个shiro授权标签导致的。继续操作到步骤e)来,然后释放掉当前断点,又来到当前断点,这其实是第二次来到相同的地方,现象如下:
    第一次:sys:c:delete
    在这里插入图片描述
    第二次:sys:c:update
    在这里插入图片描述
    第三次:sys:c:find
    在这里插入图片描述
    多次…
    这个过程,permission就跟thymeleaf中shiro授权标签对应上了。
    在这里插入图片描述

    四、确定问题所在

    至此,可以确定,控制台中打印的sql查询,是由于前端thymeleaf模板中,多次使用的shiro授权标签导致的,这也就印证了为什么doGetAuthorizationInfo(PrincipalCollection principalCollection)方法中定义的i变量,重复打印出的结果是1了。

    五、总结

    由于学shiro是通过视频学的,这样容易发现学得不系统,没方法领会到问题的关键所在。即使在排查过程中,百度有回答说是调用subject.isPermitted()就会触发doGetAuthorizationInfo(PrincipalCollection principalCollection)方法执行,但还是联想不到是自己使用了多个shiro的授权标签,从而多次调用了doGetAuthorizationInfo(PrincipalCollection principalCollection)方法。

    但更加体会到,掌握debug和深入源码去排查问题方法的重要性,只有亲身体会,才会发觉深入了解源码的重要性。

    — end

    展开全文
  • 同样,如果我们在开发中,同样的套路出现N多次,必然导致项目难以维护,就需要对设计产生严重怀疑,架构师要不明确说明为什么相同的逻辑要出现两次或更多次,要不然,嘿嘿,有你好看的!因为大量的重复性代码遍布...

    引子

    先来想想第一个问题,为什么叫模板方法呢?

    答:模板模板,肯定就是有一套固定的模式,说白了就是套路,一样的套路,似曾相识的感觉。

    同样,如果我们在开发中,同样的套路出现N多次,必然导致项目难以维护,就需要对设计产生严重怀疑,架构师要不明确说明为什么相同的逻辑要出现两次或更多次,要不然,嘿嘿,有你好看的!因为大量的重复性代码会遍布整个项目之中,所以,为了将这个套路提取出来,这时候我们就可以使用模板方法,将套路提取出一份即可。

    模板方法模式的定义

    Template Method Pattern(模板方法模式):定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

    话不多说,直接看看类图先:

    其中的templateMethod()方法即为模板方法。可以有一个或几个,一般都是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。


    注意:为了防止恶意的操作,一般模板方法都加上final关键字,不允许被重写。


    现在,我们要造出型号不同的宝马,X4和X6:

    抽象模板类

    package DesignPattern.TemplateMethodPattern;
    
    /**
     * @Date 2019/4/4 11:11
     */
    public abstract class AbstractClass {
        //鸣笛声音
        protected abstract void alarm();
    
        //发动机声音
        protected abstract void engineBoom();
    
        //启动汽车
        protected abstract void start();
    
        //模板方法
        public void templateMethod() {
            this.alarm();
            this.engineBoom();
            this.start();
        }
    }
    

    具体模板类

    public class BMW_X4 extends AbstractClass{
        //宝马X4鸣笛声是滴滴
        @Override
        protected void alarm() {
            System.out.println("滴滴!老子是宝马X4!");
        }
    
        //宝马X4引擎嗡嗡响
        @Override
        protected void engineBoom() {
            System.out.println("嗡~~~");
        }
    
        @Override
        protected void start() {
            System.out.println("宝马X4走了啊!");
        }
    }
    public class BMW_X6 extends AbstractClass {
        //宝马X6鸣笛声是哔哔
        @Override
        protected void alarm() {
            System.out.println("哔哔!老子是宝马X6!");
        }
    
        //宝马X6引擎轰轰响
        @Override
        protected void engineBoom() {
            System.out.println("轰~~~");
        }
    
        @Override
        protected void start() {
            System.out.println("宝马X6走了啊!");
        }
    }

    场景类

    public class Client {
        public static void main(String[] args) {
            AbstractClass x4 = new BMW_X4();
            AbstractClass x6 = new BMW_X6();
            //调用模板方法
            x4.templateMethod();
            x6.templateMethod();
        }
    }

    输出


    注意:抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限。


    模板方法模式的优点

    • 封装不变部分,扩展可变部分。
    • 提取公共部分的代码,便于维护。
    • 行为由父类控制,子类实现。

    模板方法模式的缺点

    一般来说,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法。但是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响

    模板方法模式的使用场景

    • 多个子类有公有的方法,并且逻辑基本相同时。
    • 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
    • 重构时。
    展开全文
  • 每个模式都描述了一个在我们的环境中不断重复出现的问题,并叙述了这个问题解决方案的要素,通过这种方式,同一解决方案能够被反复应用无数次,而每一次使用的具体方式可以不同。 亚历山大对模式的描述包括如下四...
  • Pattern(模式

    2009-05-10 16:00:00
    模式:解决某一类问题的方法论. ...为什么要用模式?因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且得到解决问题的最佳办法。 ...
     

    模式:解决某一类问题的方法论.

    Alexander给出的经典定义是:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。

    为什么要用模式?因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。

    转载于:https://www.cnblogs.com/guushuuse/archive/2009/05/10/1453671.html

    展开全文
  • 设计模式--动态代理

    2018-09-08 21:33:00
    静态代理 优点 代理是客户端不需要知道实现类是什么,怎么做,而客户端只需要知道代理即可(解...这样就会出现大量的代码重复,比如目标列增加一个方法,代理类就也要增加相应的方法 2)代理类只是一个目标...
  • 一种常见的方法是看是否存在一种模式:回答诸如“相同的问题是否重复出现?”,“它是否在某个特定的时间段出现?”和“两个问题之间是否有联系?”之类的问题,将几乎总会带来更好的诊断结果。
  • 为什么会出现代理模式? 设计模式 – 静态代理模式(线程底层原理) 文章目录1、回顾静态代理的缺点:2、实现动态代理:3、完整代码: 1、回顾静态代理的缺点: 1.代理类和委托类实现了相同的接口,代理类通过委托类...
  • Spring AOP

    2020-11-20 09:36:07
    在代码开发的过程中,开发人员可能经常会遇到在不同的需求中会出现相同的业务逻辑代码。于是这些重复的代码被封装成独立的模块,在需要的时候被调用。那么这些模块就被称为"面",而切面就是在不破坏代码结构的前提...
  • 3.1.0 在函数内定义一个字符数组,用gets函数输入字符串的时候,如果输入越界,为什么程序崩溃? 3.1.1 C++中引用与指针的区别 3.1.2 C/C++程序的内存分区 3.1.3 快速排序的思想、时间复杂度、实现以及优化方法...
  • 数据指纹就是一个文件内容的特征,理论上是没有重复的,出现重复就只有一种可能,就是文件复制前、后的两个文件,数据指纹会相同。数据指纹与文件名没有关系。 操作前准备: 无需要准备 操作步骤: 数据扫描 在...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    为什么这些问题如此频繁地出现? 60 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 60 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 60 5.17 说真的...
  • 9.8 为什么用const说明的常量不能用来定义一个数组的初始大小? 9.9 字符串和数组有什么不同? 第10章 位(bit)和字节(byte) 10.1 用什么方法存储标志(flag)效率最高? 10.2 什么是“位屏蔽(bit masking)”...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    为什么这些问题如此频繁地出现? 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 5.17 说真的,真有...
  • C语言编程要点

    2017-09-18 00:10:37
    9.8. 为什么用const说明的常量不能用来定义一个数组的初始大小? 145 9.9. 字符串和数组有什么不同? 145 第10章 位(bit)和字节(byte) 147 10.1. 用什么方法存储标志(flag)效率最高? 147 10.2. 什么是“位屏蔽(bit ...
  • java 面试题 总结

    2009-09-16 08:45:34
    为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域...
  • PowerShadow(影子系统)

    2008-10-25 07:53:32
    同上述相同默认也是在系统分区中,也造成系统分区碎片,在影子模式下也影响系统速度和系统空间——如果你往这个目录读写文件的话。当然你如果不用这个目录的话就不用设置了。  更改的方法:桌面“我的文档”...
  • 为什么这些问题如此频繁地出现? 60 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 60 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 60 5.17 说真的...
  • 为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域...
  • JAVA核心技术

    2006-02-23 15:31:04
    当一个领域逐渐成熟的时候,自然会出现很多模式。??什么是框架???框架,即framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架...
  • WIN XP蓝屏代码大全

    2013-08-08 12:29:21
    但有时仍然试图哄抢零件, 于是厂领导不得不重复停工决定(不能启动并显示蓝屏信息, 或在进行相同操作时再次出现蓝屏). 二、蓝屏的处理方法 Windows 2K/XP蓝屏信息非常多, 无法在一篇文章中全面讲解, 但他们产生的...
  • 电脑蓝屏对照码

    2019-05-05 14:16:40
    但有时仍然试图哄抢零件, 于是厂领导不得不重复停工决定(不能启动并显示蓝屏信息, 或在进行相同操作时再次出现蓝屏). 二、蓝屏的处理方法 Windows 2K/XP蓝屏信息非常多, 无法在一篇文章中全面讲解, 但他们产生的...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 128
精华内容 51
关键字:

为什么会出现重复相同模式