项目理解(六)消息队列Kafka实现及性能优化

Kafka特性:(1)高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作。(2) 可扩展性:kafka集群支持热扩展。(3)持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失。(4) 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)。(5) 高并发:支持数千个客户端同时读写。

使用场景:(1)日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。(2)消息系统:解耦和生产者和消费者、缓存消息等。(3)用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。(4) 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。(5) 流式处理:比如spark streaming和storm

Kafka对硬盘的连续读取性能是很高的,可能高于对内存的随机读取。Kafka将海量的数库存储到硬盘中,是持久化的。Broke是指kefka的服务器;Zookeeper是一个独立的应用,可以用来管理一个集群;

消息队列大致有两种实现方式:1、点对点式的,生产者往消息队列写数据,消费者从消息队列一个一个地拿数据;2、发布订阅模式:生产者将消息放到了某一个位置,可以同时有很多个消费者来订阅(读取)这个消息;生产者将消息发布到的某个位置就叫Topicpartition对位置的分区;对Topic分为了多个区域,便于多个线程同时处理,提高性能;offset为消息存放在某区域的一个索引;

Leader Replica:主副本,可以处理请求作响应;Follower Replica:从副本,只是做备份;当主副本挂掉的时候,可以从从副本中选出一个来作为新的主副本;

遇到的问题:kafka应该使用默认的版本,不然又杂又乱,版本依赖不同;

之前面向切面编程,将所有的service目录下的文件(由于只有Controller层调用了service)作为切入点访问,其中实现的是统一的日志记录:需要获取到了得到HttpServletRequest;而加上kafka消息队列在EventConsumer类中也调用了MessageService,而EventConsumer是不会出现HttpServletRequest的,所以会报空指针异常。

改进:

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        // 用户[1.2.3.4],在[xxx],访问了[com.liu.community.service.xxx()].
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(attributes == null){
            //====如果不是常规的页面Collector对service的调用,则attributes为空;如kafka中EventConsumer调用了service
            return;
        }
        HttpServletRequest request = attributes.getRequest();//得到HttpServletRequest
        String ip = request.getLocalAddr();//ip
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());//时间
        //得到切入处的:getDeclaringTypeName类名,getName方法名;
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target));
    }

 

再经过了一次封装:将消息队列信息封装为事件;

封装事件:

public class Event {
    //事件对信息进行了包装
    //封装:点赞、评论、关注三类情形;
    //topic指哪种情形;userId操作的用户id,entityId对什么实体操作的id,
    // entityType对什么实体操作的类型,entityUserId为该被操作实体的用户id
    private String topic;
    private int userId;
    private int entityType;
    private int entityId;
    private int entityUserId;
    Map<String,Object> data = new HashMap<>();//支持可扩展

    public String getTopic() {
        return topic;
    }

    public Event setTopic(String topic) {
        this.topic = topic;
        return this;//即灵活,又方便;在使用的时候可以:setTopic().setUserId().......这样来使用
    }

    public int getUserId() {
        return userId;
    }

    public Event setUserId(int userId) {
        this.userId = userId;
        return this;//即灵活,又方便;在使用的时候可以:setTopic().setUserId().......这样来使用

    }

    public int getEntityType() {
        return entityType;
    }

    public Event setEntityType(int entityType) {
        this.entityType = entityType;
        return this;//即灵活,又方便;在使用的时候可以:setTopic().setUserId().......这样来
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值