rabbitmq深入实践

news2024/11/27 18:00:19

生产者,交换机,队列,消费者
交换机和队列通过 rounting key 绑定者,rounting key 可以是#.,*.这类topic模式,
生产者发送消息内容+ rountingkey, 到达交换机后交换机检查与之绑定的队列,
如果能匹配上则把消息丢到队列里,消费者监听某个队列,如果有消息则进行消费。
生产者:confirm 消息到达 交换机 进行确认;return 消息不能到达 队列时 进行 回退

优点:
1.应用解耦
2.流量削峰
3.异步提速
缺点:
1.系统增加了消息中间件,增加了系统的复杂度,
2.要保证消息中间件的高可用

安装:
使用 Erlang (二郎神) 语言开发.
安装参考:https://blog.csdn.net/m0_67392182/article/details/126040124

wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-22.3.4.12-1.el7.x86_64.rpm/download.rpm

yum localinstall erlang-22.3.4.12-1.el7.x86_64.rpm

wget --content-disposition https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.13-1.el7.noarch.rpm/download.rpm

rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc

yum install rabbitmq-server-3.8.13-1.el7.noarch.rpm

启用rabbitmq server
systemctl start rabbitmq-server
启用管理界面
rabbitmq-plugins enable rabbitmq_management
重启
systemctl restart rabbitmq-server
访问 前端控制台
http://yourIp:15672/#/

增加用户
rabbitmqctl add_user admin admin
为用户设置权限
rabbitmqctl set_user_tags admin administrator

可能遇到的问题:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
解决方案:
在这里插入图片描述
rabbitmq 挂掉解决方案:https://blog.csdn.net/qq_41950229/article/details/105957872

在这里插入图片描述

在这里插入图片描述

启用rabbitmq server
systemctl start rabbitmq-server
启用管理界面
rabbitmq-plugins enable rabbitmq_management
重启
systemctl restart rabbitmq-server
访问 前端控制台
http://192.168.186.141:15672/#/
增加用户
rabbitmqctl add_user admin admin
给用户分配权限
rabbitmqctl set_user_tags admin administrator

rabbitmq 挂掉解决方案:https://blog.csdn.net/qq_41950229/article/details/105957872

代码链接

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

交换机和队列通过路由key绑定,生产者首先发送消息(带着key的消息)到 交换机,交换机根据接收到的key 检查与它绑定的队列,如果符合 topic则发送到该队列上

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

package org.example.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.example.utils.RabbitConstant;
import org.example.utils.RabbitUtils;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

//生产者
/*
创建 direct 交换机
* */
public class WeatherBureau {
    public static void main(String[] args) throws IOException, TimeoutException {
        Map area = new LinkedHashMap<String,String>();
        area.put("china.hunan.changsha.20221120","中国湖南长沙20221120天气数据");
        area.put("china.hubei.wuhan.20221120","中国湖北武汉20221120天气数据");
        area.put("china.hunan.changsha.20221128","中国湖南长沙20221128天气数据");
        area.put("us.cal.lsj.20221120","美国加州洛杉矶20221120天气数据");

        area.put("china.hebei.shijiazhuang.20221120","中国河北石家庄20221120天气数据");
        area.put("china.henan.zhengzhou.20221120","中国河南郑州20221120天气数据");
        area.put("china.hunan.changsha.20221129","中国湖南长沙20221129天气数据");

        Connection connection = RabbitUtils.getConnection();

        Channel channel = connection.createChannel();
        Iterator<Map.Entry<String,String>> itr = area.entrySet().iterator();
        while(itr.hasNext()){
            Map.Entry<String,String> me = itr.next();
            //arg1: 交换机的名字,arg2: 作为消息的 key
            channel.basicPublish(RabbitConstant.EXCHANGE_WEATHER_TOPIC, me.getKey(), null,me.getValue().getBytes());

        }

        channel.close();
        connection.close();
    }
}
package org.example.topic;

import com.rabbitmq.client.*;
import org.example.utils.RabbitConstant;
import org.example.utils.RabbitUtils;

import java.io.IOException;

public class BaiDu {
    public static void main(String[] args) throws IOException {
        //获取长连接
        Connection connection = RabbitUtils.getConnection();
        //获取虚拟连接
        final Channel channel = connection.createChannel();
        //声明队列信息
        channel.queueDeclare(RabbitConstant.QUEUE_BAIDU,false,false,false,null);

        //指定队列与交换机的关系以及rounting key 之间的关系

        channel.queueBind(RabbitConstant.QUEUE_BAIDU,RabbitConstant.EXCHANGE_WEATHER_TOPIC,"#.20221120");
        channel.queueBind(RabbitConstant.QUEUE_BAIDU,RabbitConstant.EXCHANGE_WEATHER_TOPIC,"china.hubei.#");
        channel.basicQos(1);

        channel.basicConsume(RabbitConstant.QUEUE_BAIDU,false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("百度天气收到气象信息: "+new String(body));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });


    }
}
package org.example.topic;

import com.rabbitmq.client.*;
import org.example.utils.RabbitConstant;
import org.example.utils.RabbitUtils;

import java.io.IOException;

//消费者
public class Sina {
    public static void main(String[] args) throws IOException {
        //获取长连接
        Connection connection = RabbitUtils.getConnection();
        //获取虚拟连接
        final Channel channel = connection.createChannel();
        //声明队列信息
        channel.queueDeclare(RabbitConstant.QUEUE_SINA,false,false,false,null);

        //指定队列与交换机的关系以及rounting key 之间的关系

        channel.queueBind(RabbitConstant.QUEUE_SINA,RabbitConstant.EXCHANGE_WEATHER_TOPIC,"*.hunan.changsha.20221128");
        channel.queueBind(RabbitConstant.QUEUE_SINA,RabbitConstant.EXCHANGE_WEATHER_TOPIC,"us.*.*.*");
        channel.basicQos(1);

        channel.basicConsume(RabbitConstant.QUEUE_SINA,false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("新浪天气收到气象信息: "+new String(body));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });

    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
confirm 确认到达 broker里,
return 表示被broker正常接收后,没有没有投递到对应的队列里面去

package org.example.confirm;

import com.rabbitmq.client.*;
import org.example.utils.RabbitConstant;
import org.example.utils.RabbitUtils;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

//生产者
/*
创建 direct 交换机
https://www.cnblogs.com/dwlovelife/p/10991371.html#%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3
* */
public class WeatherBureau {
    public static void main(String[] args) throws IOException, TimeoutException {
        Map area = new LinkedHashMap<String,String>();
        area.put("china.hunan.changsha.20221120","中国湖南长沙20221120天气数据");
        area.put("china.hubei.wuhan.20221120","中国湖北武汉20221120天气数据");
        area.put("china.hunan.changsha.20221128","中国湖南长沙20221128天气数据");
        area.put("us.cal.lsj.20221120","美国加州洛杉矶20221120天气数据");

        area.put("china.hebei.shijiazhuang.20221120","中国河北石家庄20221120天气数据");
        area.put("china.henan.zhengzhou.20221120","中国河南郑州20221120天气数据");
        area.put("china.hunan.changsha.20221129","中国湖南长沙20221129天气数据");
        area.put("china.hunan.changsha.20221129","中国湖南长沙20221129天气数据");
        area.put("cn","中国湖南长沙20221129天气数据");

        Connection connection = RabbitUtils.getConnection();

        Channel channel = connection.createChannel();
        //开启confirm 监听模式
        channel.confirmSelect();
        //到达到broker中被确认
        channel.addConfirmListener(new ConfirmListener() {
            public void handleAck(long l, boolean b) throws IOException {
                // 第二个参数代表接收的数据是否为批量接收,一般我们用不到
                System.out.println("消息已被Broker接收,Tag: "+l);
            }

            public void handleNack(long l, boolean b) throws IOException {
                System.out.println("消息已被Broker接收,Tag: "+l);
            }

        });
        //到达broker被确认后,但是找不到对应的队列投递
        channel.addReturnListener(new ReturnCallback() {
            public void handle(Return aReturn) {
                System.err.println("============================");
                System.err.println("Return 编码: "+ aReturn.getReplyCode() + "-Return 描述"+ aReturn.getReplyText());
                System.err.println("交换机: "+ aReturn.getExchange()+"-路由key: "+ aReturn.getRoutingKey());
                System.err.println("Return 主题: "+new String(aReturn.getBody()));
                System.err.println("==============================");
            }
        });

        Iterator<Map.Entry<String,String>> itr = area.entrySet().iterator();

        while(itr.hasNext()){
            Map.Entry<String,String> me = itr.next();
            //arg1: 交换机的名字,arg2: 作为消息的routing key,arg3:如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中
            channel.basicPublish(RabbitConstant.EXCHANGE_WEATHER_TOPIC, me.getKey(), true,null,me.getValue().getBytes());
        }

        //这里不能关掉
//        channel.close();
        //这里不能关掉
//        connection.close();
    }
}

在这里插入图片描述

https://github.com/ranhaoliu/rabbitmq-demo

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
生产者:

<!--===============================TTL 开始=======================    -->
    <rabbit:queue name="test_queue_ttl" id="test_queue_ttl">
        <rabbit:queue-arguments>
            <entry key="x-message-ttl" value="10000" value-type="java.lang.Integer"></entry>
        </rabbit:queue-arguments>
    </rabbit:queue>

    <rabbit:topic-exchange name="test_exchange_ttl">
            <rabbit:bindings>
                <rabbit:binding pattern="ttl.#" queue="test_queue_ttl"></rabbit:binding>
            </rabbit:bindings>
    </rabbit:topic-exchange>
@Test
public void testTtl(){
    for(int i=0;i<10;i++){
        rabbitTemplate.convertAndSend("test_exchange_ttl","ttl.baiqi","message ttl ...");
    }
}

10秒后会消失
在这里插入图片描述

死信队列
在这里插入图片描述

生产者:

<!--
    死信队列:
        1.声明正常得队列(test_queue_dlx)和交换机(test_exchange_dlx)
        2.声明死信队列(queue_dlx)和死信交换机(exchange_dlx)
        3.正常队列绑定死信交换机
           设置两个参数:
                   * x-dead-letter-exchange: 死信交换机名称
                   * x-dead-letter-routing-key: 发送给死信交换机的 routingkey
 -->

    <!--  1.1 声明正常得队列(test_queue_dlx)和交换机(test_exchange_dlx) -->
    <rabbit:queue name="test_queue_dlx" id="test_queue_dlx">
        <rabbit:queue-arguments>
            <!--3.1: x-dead-letter-exchange 死信交换机名称; value 的值是 2.2 中的声明的死信交换机名称 -->
            <entry key="x-dead-letter-exchange" value="exchange_dlx"></entry>
            <!--3.2: x-dead-letter-routing-key: 发送给死信交换机的routingkey-->
            <entry key="x-dead-letter-routing-key" value="dlx.hehe"></entry>
            <!--4.1 设置队列的过期时间 ttl-->
            <entry key="x-message-ttl" value="1000" value-type="java.lang.Integer"></entry>
            <!--4.2 设置队列的长度限制 max-length-->
            <entry key="x-max-length" value="10" value-type="java.lang.Integer"></entry>
        </rabbit:queue-arguments>
    </rabbit:queue>

    <!--1.2 声明正常的交换机   -->
    <rabbit:topic-exchange name="test_exchange_dlx">
        <rabbit:bindings>
            <rabbit:binding pattern="test.dlx.#" queue="test_queue_dlx"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <!--2.1 声明死信队列(queue_dlx) -->
    <rabbit:queue name="queue_dlx" id="queue_dlx"></rabbit:queue>
    <!--2.2 死信交换机(exchange_dlx)-->
    <rabbit:topic-exchange name="exchange_dlx">
        <rabbit:bindings>
            <rabbit:binding pattern="dlx.#" queue="queue_dlx"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>
<!--=====================死信队列结束=======================
/*
* 发送测试死信消息:
* 1.过期时间
* 2.长度限制
* 3.消息拒收
* */
    @Test
    public void testDlx(){
        rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.hehe","死信消息...");
    }

在这里插入图片描述
一些细节:
在这里插入图片描述
在这里插入图片描述
生产者:

<!--=======================延迟队列=============================-->
    <!--
    延迟队列:
        1.声明正常得队列(order_queue)和交换机(order_exchange)
        2.声明死信队列(order_queue_dlx)和死信交换机(order_exchange_dlx)
        3.绑定,设置正常队列过期时间为30分钟
            正常队列绑定死信交换机
           设置两个参数:
                   * x-dead-letter-exchange: 死信交换机名称
                   * x-dead-letter-routing-key: 发送给死信交换机的 routingkey
 -->

    <!--  1.1 声明正常得队列(order_queue)和交换机(order_exchange) -->
    <rabbit:queue name="order_queue" id="order_queue">
        <rabbit:queue-arguments>
        <!--3.绑定,设置正常队列过期时间为30分钟,此处设置10秒钟演示来用           -->
            <!--3.1: x-dead-letter-exchange 死信交换机名称; value 的值是 2.2 中的声明的死信交换机名称 -->
            <entry key="x-dead-letter-exchange" value="order_exchange_dlx"></entry>
            <!--3.2: x-dead-letter-routing-key: 发送给死信交换机的routingkey-->
            <entry key="x-dead-letter-routing-key" value="dlx.order.cannel"></entry>
            <!--4.1 设置队列的过期时间 ttl-->
            <entry key="x-message-ttl" value="1000" value-type="java.lang.Integer"></entry>
        </rabbit:queue-arguments>
    </rabbit:queue>

    <!--1.2 声明正常的交换机   -->
    <rabbit:topic-exchange name="order_exchange">
        <rabbit:bindings>
            <rabbit:binding pattern="order.#" queue="order_queue"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <!--2.1 声明死信队列(order_queue_dlx) -->
    <rabbit:queue name="order_queue_dlx" id="order_queue_dlx"></rabbit:queue>
    <!--2.2 死信交换机(exchange_dlx)-->
    <rabbit:topic-exchange name="order_exchange_dlx">
        <rabbit:bindings>
            <rabbit:binding pattern="dlx.order.#" queue="order_queue_dlx"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>

消费者:

package org.example.rabbitmq.listener;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

@Component
public class OrderListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {

        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try{
            //1.接收转化消息
            System.out.println("message: "+new String(message.getBody()));
            //2.进行业务处理
            System.out.println("进行业务逻辑处理...");
            System.out.println("根据订单id查询其状态...");
            System.out.println("判断状态是否为支付成功...");
            System.out.println("取消订单,回滚库存..");

            //3.手动签收
            channel.basicAck(deliveryTag,true);
        }catch (Exception e){
            //拒绝签收
           /*第三个参数:requeue:重回队列。如果设置为true,则消息从新回到queue,broker会重新发送该消息给消费端,
           如果为false则拒绝签收
           * */
            channel.basicNack(deliveryTag,true,true);
//           channel.basicNack(deliveryTag,true,false);
        }

    }

    @Override
    public void onMessage(Message message) {

    }

    @Override
    public void containerAckMode(AcknowledgeMode mode) {

    }

}
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="2">
    <rabbit:listener ref="orderListener" queue-names="order_queue_dlx"></rabbit:listener>
</rabbit:listener-container>

先运行消费者,再运行生产者测试代码发现 10秒钟后,消费者开始消费
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

== rabbitmq 集群:==
https://cloud.tencent.com/developer/article/1631148
https://www.leeks.info/zh_CN/latest/Linux_Notes/rabbitmq/RabbitMQ.html#id2
rabbitmq高可用集群搭建踩坑

systemctl start rabbitmq-server.service
1.环境准备(需重启客户端)
hostnamectl set-hostname m1
hostnamectl set-hostname m2
2.统一 erlang.cookie 文件中 cookie值 将m1 中的 .erlang.cookie 同步到 m2 中(在m1机器操作)
scp /var/lib/rabbitmq/.erlang.cookie m2:/var/lib/rabbitmq/.erlang.cookie
或者 scp /var/lib/rabbitmq/.erlang.cookie m2的ip:/var/lib/rabbitmq/.erlang.cookie
3.Rabbitmq 集群添加节点(在m2机器上操作)
#重启 m2机器中 rabbitmq 的服务
rabbitmqctl stop_app

rabbitmqctl join_cluster --ram rabbit@m1 (m1上操作)
rabbitmqctl start_app 
#启用管理界面
rabbitmq-plugins enable rabbitmq_management
systemctl restart rabbitmq-server.service
#4, 查看集群信息
rabbitmqctl cluster_status

可能出现的问题:
unable to connect to epmd (port 4369) on m1: nxdomain (non-existing domain)
在这里插入图片描述
最总解决: rabbitmq高可用集群搭建踩坑

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

#1.安装
yum install haproxy
#2.配置haproxy.cfg 文件 具体参考 如下 1.5.2 配置HAProxy
vim /etc/haproxy/haproxy.cfg
#3.启动 haproxy
systemctl start haproxy
#4.查看haproxy 进程状态
systemctl status haproxy.service
#状态如下说明 已经启动成功 Active: active(running)
#访问如下地址对mq 结点进行监控
http://服务器Ip:1080/haproxy_stats
#代码中访问mq的地址则变为haproxy的地址:5672

1.5.2

#对mq集群进行监听
listen rabbitmq_cluster
    bind 0.0.0.0:5672
    option tcplog
    mode tcp
    option clitcpka
    timeout connect 1s
    timeout client 10s
    timeout server 10s
    balance roundrobin
    server node1 192.168.1.9:5672 check inter 5s rise 2 fall 3
    server node2 192.168.1.10:5672 check inter 5s rise 2 fall 3
#开启haproxy 监控服务
listen http_front
    bind 0.0.0.0:1090
    stats refresh 30s
    stats uri /haproxy_stats
    stats auth admin:admin

效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/428858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Yolov5之common.py文件解读

深度学习训练营原文链接前言0.导入需要的包以及基本配置1.基本组件1.1 autopad1.2 ConvDWConv模块1.3TransformerLayer模块1.4 Bottleneck和BottleneckCSPBottleneck模型结构1.5 CrossConv模块1.6 C3模块基于C3的改进1.7SPP1.8Focus模块1.9 Concat模块1.10 Contract和Expand1.1…

好东西!!!多亏几位大牛整理的面试题,让我成功上岸!!

凡事预则立&#xff0c;不预则废。相信很多程序员朋友在跳槽前都会临阵磨枪&#xff0c;在网络上搜集一些面试题进行准备。 然而&#xff0c;当机会来临时&#xff0c;却发现这些面试题往往“不快也不光”.... 由于Java面试涉及的范围很广&#xff0c;很杂&#xff0c;而且技…

使用MyBatis实现简单查询

文章目录一&#xff0c;创建数据库与表&#xff08;一&#xff09;在Navicat里创建MySQL数据库testdb&#xff08;二&#xff09;创建用户表 - t_user&#xff08;三&#xff09;在用户表里插入3条记录二&#xff0c;案例演示MyBatis基本使用&#xff08;一&#xff09;创建Mav…

解决idea每次打开新的项目都需要重新配置maven

原理&#xff1a;就是通过 idea 来进行全局配置【非当前工程配置】 IDEA 版本&#xff1a;2023.1 如何查看版本信息 &#xff1f; 【主菜单】——【帮助】——【关于】 我在网上查找了许多文章 &#xff0c;我混淆了一点&#xff01;当前工程的设置 & 全局设置 不在一个地方…

马斯克掷重金收购英

人前主义&#xff0c;人后生意。在带领一众科技圈大佬签署了呼吁暂停研发比GPT-4更强AI模型的公开信后不久&#xff0c;马斯克却转头豪掷千金收购了10000块英伟达GPU。 一些网友吐槽&#xff0c;以马老板的格局而言&#xff0c;这次价值过亿的投资绝对不是为了借着AI概念火爆来…

2021年 团体程序设计天梯赛——题解集

Hello各位童学大家好&#xff01;&#x1f60a;&#x1f60a;&#xff0c;茫茫题海你我相遇即是缘分呐&#xff0c;或许日复一日的刷题已经让你感到疲惫甚至厌倦了&#xff0c;但是我们真的真的已经达到了我们自身极限了吗&#xff1f;少一点自我感动&#xff0c;没有结果前别太…

[FREERTOS] 任务的创建、删除、调度与状态

1.什么是任务&#xff1f; 我的理解是&#xff1a;任务像是进程/线程&#xff0c;创建一个任务就会开辟一个空间&#xff0c;每一个任务都是独立的执行相应的动作互不干扰&#xff0c;就比如玩游戏&#xff0c;陪女朋友&#xff0c;任务通常都会有一个while(1)死循环 2.与任务创…

使用cloudflare代理flask启用https服务

原文来自&#xff1a;使用cloudflare代理flask启用https服务 | 夜空中最亮的星 欢迎大家留言讨论 问题1&#xff1a;使用cloudflare的dns回源服务器的时候&#xff0c;出现了http和https不断反复重定向 问题2: flask只能启用http服务&#xff0c;需要启用https 步骤 服务器&…

浅谈[Linux搭建GitLab私有仓库,并内网穿透实现公网访问]

转载自远控源码文章&#xff1a;Linux搭建GitLab私有仓库&#xff0c;并内网穿透实现公网访问 前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务。 Gitlab是被广泛使用的基于git的开源代码管理平…

报错解决:Python ‘NoneType‘ object is not subscriptable , 获取到的数据为None,需要保留数据

人生苦短&#xff0c;我用python 爬取某DB电影数据的时候&#xff0c; 在获取内容的时候出现 NoneType object is not subscriptablePython 资料报错交流:点击此处跳转文末名片获取 获取数据的部分代码是&#xff1a; writer_avatars (writers_list[wi][avatars][small]) …

Linux0.11 信号(十二)

系列文章目录 Linux 0.11启动过程分析&#xff08;一&#xff09; Linux 0.11 fork 函数&#xff08;二&#xff09; Linux0.11 缺页处理&#xff08;三&#xff09; Linux0.11 根文件系统挂载&#xff08;四&#xff09; Linux0.11 文件打开open函数&#xff08;五&#xff09…

前端webpack项目性能优化——体积压缩和compression-webpack-plugin的使用

前端webpack项目性能优化——体积压缩和compression-webpack-plugin的使用需求优化结果需求 脚手架搭建的项目&#xff0c;会默认开启sourceMap&#xff0c;此时打包下来的包会很大&#xff0c;如图&#xff1a;map文件比所有js文件都大&#xff0c;会导致包整体体积过大&…

NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031

然后我们再来看一下如何把json内容,转换成hive支持的文本格式,其实还是一个格式转换对吧 首先看一下用到的处理器,可以看到这里我们用到了evaluateJsonPath处理器,这个处理器用来提取json中的熟悉,然后ReplaceText处理器用来替换掉FlowFile中的属性的内容 首先看一下这个Evalua…

【Python-Conda】Conda操作解读 pip 和 conda 的区别

【Python-Conda】Conda操作解读 & conda与pip的区别 文章目录【Python-Conda】Conda操作解读 & conda与pip的区别1. 介绍2. conda 操作2.1 创建环境2.2 查看conda已创建的环境2.3 删除环境2.3.1 删除虚拟环境中的包2.4 激活&#xff08;失活&#xff09;环境2.4.1 激活…

OpenAI Embedding:快速实现聊天机器人(三)

theme: orange 本文正在参加「金石计划」 接上文OpenAI Embedding&#xff1a;快速实现聊天机器人(二)有讲到聊天机器人的架构和流程&#xff0c;这篇开始通过代码讲讲具体实现。 前言 这篇文章为了降低实现的难度&#xff0c;下图中提供存储和向量相似度搜索的Redis(Redis Sea…

智媒ai在线伪原创-python文本自动伪原创

文章伪原创工具的优势 文章伪原创工具是一类自然语言处理工具&#xff0c;通过对原始文本进行语言转换、替换、重组等方式&#xff0c;生成与原始文本相似但不完全相同的新文本。这种工具的优势主要包括以下几点&#xff1a; 提高工作效率&#xff1a;使用文章伪原创工具可以快…

第三章 传输层

传输层基本服务 传输层核心任务是为应用进程之间提供端到端的逻辑通信服务传输层主要实现功能&#xff1a;传输层寻址、对应用层报文进行分段和重组、对报文进行差错检测、实现进程间的端到端的可靠数据传输控制、面向应用层实现复用与分解、实现端到端的流量控制、拥塞控制 …

C++中的引用

上一次&#xff0c;我们只是浅浅的提了一下引用‘&’&#xff0c;那么今天&#xff0c;我们就正式减少一下引用&#xff0c;以及引用是什么&#xff0c;还有就是引用和指针的区别&#xff0c;引用的特点 首先&#xff0c;我们回顾一下什么是引用&#xff0c;引用就是取别名…

MapReduce原理

MapReduce 编程规范 MapReduce 的开发一共有八个步骤, 其中 Map 阶段分为 2 个步骤&#xff0c;Shuffle 阶段 4 个步骤&#xff0c;Reduce 阶段分为 2 个步骤Map 阶段 2 个步骤 设置 InputFormat 类, 将数据切分为 Key-Value(K1和V1) 对, 输入到第二步自定义 Map 逻辑, 将第一…

十五周算法训练营——链表专题

今天是十五周算法训练营的第三周&#xff0c;主要讲链表专题&#xff0c;包含&#xff1a;反转链表、移除链表、交换链表、链表相交、删除链表中的倒数第N个节点、环形链表II。&#xff08;欢迎加入十五周算法训练营&#xff0c;与小伙伴一起卷算法——文章末尾进群&#xff09…