最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RabbitMQ在微服務(wù)架構(gòu)中的落地:消息推送?/?解耦?/?削峰填谷

 更新時間:2026年05月07日 09:47:22   作者:知遠漫談  
本文介紹了RabbitMQ在微服務(wù)架構(gòu)中的三大應(yīng)用場景:消息推送、服務(wù)解耦和削峰填谷,通過實際代碼示例展示了如何在實際項目中應(yīng)用RabbitMQ實現(xiàn)這些模式,感興趣的朋友一起看看吧

在現(xiàn)代分布式系統(tǒng)和微服務(wù)架構(gòu)中,服務(wù)之間的通信變得越來越復(fù)雜。傳統(tǒng)的同步調(diào)用方式雖然直觀,但在高并發(fā)、高可用性要求的場景下,往往面臨性能瓶頸、系統(tǒng)耦合度高、容錯能力差等問題。為了解決這些挑戰(zhàn),消息隊列(Message Queue) 成為了微服務(wù)架構(gòu)中不可或缺的中間件組件。

其中,RabbitMQ 作為一款開源、穩(wěn)定、功能豐富的消息中間件,憑借其靈活的路由機制、可靠的消息投遞保障以及良好的社區(qū)生態(tài),被廣泛應(yīng)用于各類企業(yè)級系統(tǒng)中。

本文將深入探討 RabbitMQ 在微服務(wù)架構(gòu)中的三大核心應(yīng)用場景:

  • 消息推送(異步通知)
  • 服務(wù)解耦(降低系統(tǒng)耦合度)
  • 削峰填谷(流量緩沖與平滑處理)

我們將結(jié)合 Java(Spring Boot)代碼示例,詳細說明如何在實際項目中落地這些模式,并通過 Mermaid 圖表直觀展示系統(tǒng)架構(gòu)與數(shù)據(jù)流向。同時,文章會穿插一些實用的最佳實踐和外部參考鏈接,幫助你構(gòu)建更健壯、可擴展的微服務(wù)系統(tǒng)。

一、為什么選擇 RabbitMQ?

在眾多消息中間件(如 Kafka、RocketMQ、ActiveMQ、Pulsar)中,RabbitMQ 以其易用性、協(xié)議標準(AMQP)、管理界面友好、插件生態(tài)豐富等優(yōu)勢,在中小型系統(tǒng)或?qū)ο⒖煽啃砸筝^高的場景中表現(xiàn)尤為突出。

?? AMQP(Advanced Message Queuing Protocol) 是一個開放標準的應(yīng)用層協(xié)議,專為消息中間件設(shè)計。RabbitMQ 是 AMQP 0.9.1 的最主流實現(xiàn)。

RabbitMQ 的核心優(yōu)勢包括:

  • ? 高可靠性:支持消息持久化、確認機制(Publisher Confirm / Consumer Ack)
  • ? 靈活路由:通過 Exchange + Binding + Routing Key 實現(xiàn)復(fù)雜路由邏輯
  • ? 流量控制:支持 QoS(Quality of Service),防止消費者過載
  • ? 可視化管理:提供 Web 管理界面(需啟用 rabbitmq_management 插件)
  • ? 多語言支持:官方提供 Java、Python、Go、.NET 等客戶端 SDK

?? 官方文檔是學(xué)習(xí) RabbitMQ 的最佳起點:https://www.rabbitmq.com/documentation.html

二、RabbitMQ 核心概念回顧

在深入應(yīng)用場景前,我們先快速回顧 RabbitMQ 的幾個關(guān)鍵組件:

  • Producer(生產(chǎn)者):發(fā)送消息的應(yīng)用。
  • Consumer(消費者):接收并處理消息的應(yīng)用。
  • Queue(隊列):存儲消息的緩沖區(qū),先進先出(FIFO)。
  • Exchange(交換機):接收生產(chǎn)者消息并根據(jù)規(guī)則路由到一個或多個隊列。
    • 常見類型:direct、fanout、topic、headers
  • Binding(綁定):定義 Exchange 與 Queue 之間的關(guān)聯(lián)規(guī)則(通常包含 Routing Key)。
  • Routing Key(路由鍵):生產(chǎn)者發(fā)送消息時指定的字符串,用于匹配 Binding。

?? 一個 Exchange 可以綁定多個 Queue,一個 Queue 也可以被多個 Exchange 綁定。

三、場景一:消息推送(異步通知)

3.1 問題背景

在電商系統(tǒng)中,用戶下單后通常需要觸發(fā)一系列后續(xù)操作:

  • 發(fā)送訂單確認郵件
  • 推送微信/短信通知
  • 更新用戶積分
  • 記錄操作日志
  • 調(diào)用風(fēng)控系統(tǒng)

如果這些操作都通過同步 HTTP 調(diào)用完成,會導(dǎo)致:

  • 主流程響應(yīng)時間變長(用戶體驗差)
  • 某個下游服務(wù)故障會阻塞整個訂單流程
  • 系統(tǒng)耦合度高,難以獨立演進

3.2 解決方案:使用 RabbitMQ 異步通知

我們將“訂單創(chuàng)建”事件發(fā)布到 RabbitMQ,由各個消費者異步處理各自的任務(wù)。

PointsService SMSService EmailService RabbitMQ OrderService User PointsService SMSService EmailService RabbitMQ OrderService User 下單請求 發(fā)布 order.created 事件 返回“下單成功” 消費事件 → 發(fā)郵件 消費事件 → 發(fā)短信 消費事件 → 加積分

3.3 Java 代碼實現(xiàn)(Spring Boot)

步驟 1:添加依賴(pom.xml)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

步驟 2:配置 RabbitMQ 連接(application.yml)

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

步驟 3:定義 Exchange、Queue 和 Binding

@Configuration
public class RabbitMQConfig {
    public static final String ORDER_EXCHANGE = "order.exchange";
    public static final String ORDER_CREATED_QUEUE = "order.created.queue";
    public static final String ORDER_ROUTING_KEY = "order.created";
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange(ORDER_EXCHANGE);
    }
    @Bean
    public Queue orderCreatedQueue() {
        return QueueBuilder.durable(ORDER_CREATED_QUEUE).build();
    }
    @Bean
    public Binding bindingOrderCreated(Queue orderCreatedQueue, DirectExchange orderExchange) {
        return BindingBuilder.bind(orderCreatedQueue)
                .to(orderExchange)
                .with(ORDER_ROUTING_KEY);
    }
}

?? 使用 DirectExchange,Routing Key 必須完全匹配才能路由到隊列。

步驟 4:生產(chǎn)者(訂單服務(wù))

@Service
public class OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public void createOrder(Order order) {
        // 1. 保存訂單到數(shù)據(jù)庫
        orderRepository.save(order);
        // 2. 發(fā)布事件(異步)
        rabbitTemplate.convertAndSend(
            RabbitMQConfig.ORDER_EXCHANGE,
            RabbitMQConfig.ORDER_ROUTING_KEY,
            new OrderCreatedEvent(order.getId(), order.getUserId(), order.getAmount())
        );
        // 3. 立即返回,不等待下游處理
    }
}

步驟 5:消費者(郵件服務(wù))

@Component
public class EmailConsumer {
    @RabbitListener(queues = RabbitMQConfig.ORDER_CREATED_QUEUE)
    public void handleOrderCreated(OrderCreatedEvent event) {
        try {
            // 發(fā)送郵件邏輯
            emailService.sendOrderConfirmation(event.getOrderId());
        } catch (Exception e) {
            // 記錄日志,可考慮重試或死信隊列
            log.error("Failed to send email for order: {}", event.getOrderId(), e);
            throw new AmqpRejectAndDontRequeueException(e); // 避免無限重試
        }
    }
}

?? 注意:消費者方法拋出異常時,默認會 requeue(重新入隊),可能導(dǎo)致死循環(huán)。建議捕獲異常并決定是否拒絕消息。

3.4 優(yōu)勢總結(jié)

  • ? 主流程響應(yīng)快:用戶無需等待郵件/短信發(fā)送完成
  • ? 故障隔離:郵件服務(wù)宕機不影響訂單創(chuàng)建
  • ? 可擴展性強:新增“推送 App 通知”只需新增一個消費者

四、場景二:服務(wù)解耦(降低系統(tǒng)耦合度)

4.1 什么是耦合?為什么需要解耦?

在微服務(wù)架構(gòu)中,“耦合”指服務(wù)之間存在強依賴關(guān)系。例如:

  • 服務(wù) A 直接調(diào)用服務(wù) B 的 REST API
  • 服務(wù) B 的接口變更會導(dǎo)致服務(wù) A 失敗
  • 服務(wù) B 不可用時,服務(wù) A 也無法工作

這種同步調(diào)用鏈使得系統(tǒng)脆弱、難以維護。

4.2 RabbitMQ 如何實現(xiàn)解耦?

通過事件驅(qū)動架構(gòu)(Event-Driven Architecture, EDA),服務(wù)之間不再直接調(diào)用,而是通過 RabbitMQ 交換“事件”。

?? 事件驅(qū)動架構(gòu)的核心思想:“發(fā)布-訂閱”模型,生產(chǎn)者只關(guān)心發(fā)布事件,不關(guān)心誰消費。

在這個模型中:

  • 用戶服務(wù)只需發(fā)布 user.registered 事件
  • 積分、營銷、審計服務(wù)各自監(jiān)聽該事件,互不影響
  • 新增“推薦服務(wù)”?只需訂閱同一事件即可,無需修改用戶服務(wù)

4.3 Java 代碼實現(xiàn):用戶注冊事件

定義事件對象(建議使用 JSON 序列化)

public class UserRegisteredEvent {
    private String userId;
    private String email;
    private LocalDateTime registerTime;
    // 構(gòu)造函數(shù)、getter/setter 略
}

配置 Fanout Exchange(廣播模式)

@Configuration
public class UserEventConfig {
    public static final String USER_FANOUT_EXCHANGE = "user.fanout.exchange";
    public static final String USER_REGISTERED_QUEUE_POINTS = "user.registered.queue.points";
    public static final String USER_REGISTERED_QUEUE_MARKETING = "user.registered.queue.marketing";
    @Bean
    public FanoutExchange userFanoutExchange() {
        return new FanoutExchange(USER_FANOUT_EXCHANGE);
    }
    @Bean
    public Queue pointsQueue() {
        return QueueBuilder.durable(USER_REGISTERED_QUEUE_POINTS).build();
    }
    @Bean
    public Queue marketingQueue() {
        return QueueBuilder.durable(USER_REGISTERED_QUEUE_MARKETING).build();
    }
    @Bean
    public Binding bindPointsToFanout(Queue pointsQueue, FanoutExchange exchange) {
        return BindingBuilder.bind(pointsQueue).to(exchange);
    }
    @Bean
    public Binding bindMarketingToFanout(Queue marketingQueue, FanoutExchange exchange) {
        return BindingBuilder.bind(marketingQueue).to(exchange);
    }
}

?? FanoutExchange 會將消息廣播到所有綁定的隊列,忽略 Routing Key。

用戶服務(wù)發(fā)布事件

@Service
public class UserService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public void registerUser(String email) {
        // 1. 保存用戶
        User user = userRepository.save(new User(email));
        // 2. 發(fā)布事件(無 Routing Key)
        rabbitTemplate.convertAndSend(
            UserEventConfig.USER_FANOUT_EXCHANGE,
            "", // Fanout 不需要 Routing Key
            new UserRegisteredEvent(user.getId(), email, LocalDateTime.now())
        );
    }
}

積分服務(wù)消費

@Component
public class PointsConsumer {
    @RabbitListener(queues = UserEventConfig.USER_REGISTERED_QUEUE_POINTS)
    public void onUserRegistered(UserRegisteredEvent event) {
        pointsService.addWelcomePoints(event.getUserId(), 100);
    }
}

營銷服務(wù)消費

@Component
public class MarketingConsumer {
    @RabbitListener(queues = UserEventConfig.USER_REGISTERED_QUEUE_MARKETING)
    public void onUserRegistered(UserRegisteredEvent event) {
        marketingService.sendWelcomeCoupon(event.getEmail());
    }
}

4.4 解耦帶來的好處

  • ?? 獨立部署:各服務(wù)可獨立開發(fā)、測試、上線
  • ?? 技術(shù)棧自由:消費者可用不同語言(如 Python 處理數(shù)據(jù)分析)
  • ?? 彈性伸縮:高負載時可單獨擴容某個消費者
  • ??? 容錯性增強:一個消費者失敗不影響其他消費者

?? 關(guān)于事件驅(qū)動架構(gòu)的更多思考,可參考 Martin Fowler 的經(jīng)典文章:https://martinfowler.com/articles/201701-event-driven.html

五、場景三:削峰填谷(流量緩沖與平滑處理)

5.1 什么是“削峰填谷”?

在秒殺、搶購、大促等場景中,系統(tǒng)可能在短時間內(nèi)收到海量請求(如每秒 10 萬次),遠超后端處理能力(如每秒 1000 次)。

若直接處理,會導(dǎo)致:

  • 數(shù)據(jù)庫連接池耗盡
  • CPU/內(nèi)存飆升,服務(wù)崩潰
  • 用戶請求大量超時或失敗

削峰填谷的核心思想是:用消息隊列作為緩沖區(qū),將突發(fā)流量“拉平”,讓后端以穩(wěn)定速率處理。

5.2 實際案例:秒殺系統(tǒng)

假設(shè)我們要實現(xiàn)一個秒殺功能:

  • 商品庫存 100 件
  • 開放 10 秒,預(yù)計 10 萬用戶參與
  • 后端最多處理 500 QPS

如果不做限流,數(shù)據(jù)庫將直接被打垮。

5.3 使用 RabbitMQ 緩沖請求

我們將用戶的“秒殺請求”先放入 RabbitMQ,后端以固定速率(如 100 TPS)從隊列中消費,檢查庫存并下單。

DB SeckillConsumer RabbitMQ SeckillController User DB SeckillConsumer RabbitMQ SeckillController User loop [高并發(fā)請求] alt [庫存充足] [庫存不足] loop [穩(wěn)定消費] 提交秒殺請求 入隊(極快) 拉取消息 檢查庫存 & 扣減 秒殺成功 秒殺失敗

5.4 Java 代碼實現(xiàn)

定義秒殺隊列

@Configuration
public class SeckillConfig {
    public static final String SECKILL_QUEUE = "seckill.queue";
    @Bean
    public Queue seckillQueue() {
        // 設(shè)置隊列長度限制,防止內(nèi)存溢出
        return QueueBuilder.durable(SECKILL_QUEUE)
                .maxLength(50000) // 最多緩存 5 萬條
                .build();
    }
}

控制器:快速入隊

@RestController
public class SeckillController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @PostMapping("/seckill")
    public ResponseEntity<String> seckill(@RequestParam String userId, @RequestParam String goodsId) {
        // 1. 基礎(chǔ)校驗(如登錄、參數(shù)合法性)
        if (!validate(userId, goodsId)) {
            return ResponseEntity.badRequest().body("Invalid request");
        }
        // 2. 快速入隊(毫秒級響應(yīng))
        rabbitTemplate.convertAndSend(
            SeckillConfig.SECKILL_QUEUE,
            new SeckillRequest(userId, goodsId, System.currentTimeMillis())
        );
        // 3. 立即返回“請求已接收”,不承諾結(jié)果
        return ResponseEntity.ok("Request accepted. Please wait for result.");
    }
}

消費者:限速處理

@Component
public class SeckillConsumer {
    @Autowired
    private GoodsService goodsService;
    // 限制每個消費者實例的并發(fā)數(shù)
    @RabbitListener(queues = SeckillConfig.SECKILL_QUEUE, concurrency = "1-3")
    public void processSeckill(SeckillRequest request) {
        try {
            boolean success = goodsService.trySeckill(request.getUserId(), request.getGoodsId());
            if (success) {
                // 通知用戶成功(如 WebSocket / 短信)
                notificationService.notifySuccess(request.getUserId());
            } else {
                notificationService.notifyFailure(request.getUserId());
            }
        } catch (Exception e) {
            log.error("Seckill failed", e);
            // 可記錄到死信隊列供人工處理
        }
    }
}

配置 QoS(限流)

application.yml 中設(shè)置:

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 10  # 每次最多預(yù)取 10 條消息
        acknowledge-mode: manual  # 手動 ACK

并在消費者中手動確認:

@RabbitListener(queues = SeckillConfig.SECKILL_QUEUE)
public void processSeckill(SeckillRequest request, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
    try {
        boolean success = goodsService.trySeckill(...);
        // 業(yè)務(wù)處理...
        channel.basicAck(tag, false); // 手動 ACK
    } catch (Exception e) {
        try {
            channel.basicNack(tag, false, true); // 重回隊列 or 進入死信
        } catch (IOException ioEx) {
            log.error("Nack failed", ioEx);
        }
    }
}

5.5 削峰填谷的關(guān)鍵點

  • ?? 快速響應(yīng):生產(chǎn)者只負責入隊,不處理業(yè)務(wù)
  • ?? 限速消費:通過 prefetchconcurrency 控制消費速度
  • ?? 隊列長度限制:避免內(nèi)存爆炸(maxLength
  • ?? 失敗處理:超時、庫存不足等應(yīng)有明確反饋機制
  • ?? 監(jiān)控告警:隊列積壓量是重要指標

?? RabbitMQ 官方對流量控制的說明:https://www.rabbitmq.com/flow-control.html

六、可靠性保障:消息不丟失

在金融、支付等場景中,消息可靠性至關(guān)重要。RabbitMQ 提供了多種機制確保消息不丟失。

6.1 消息丟失的三個環(huán)節(jié)

  1. 生產(chǎn)者 → RabbitMQ:網(wǎng)絡(luò)中斷導(dǎo)致消息未到達
  2. RabbitMQ 內(nèi)部:Broker 宕機,內(nèi)存消息丟失
  3. RabbitMQ → 消費者:消費者處理失敗且未重試

6.2 解決方案

6.2.1 生產(chǎn)者確認(Publisher Confirm)

開啟 Confirm 模式,RabbitMQ 收到消息后會回調(diào)生產(chǎn)者。

// 配置
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
    if (ack) {
        log.info("Message confirmed");
    } else {
        log.error("Message lost: {}", cause);
        // 可重發(fā)或記錄 DB
    }
});
// 發(fā)送時指定 CorrelationData
rabbitTemplate.convertAndSend(exchange, routingKey, message, 
    msg -> {
        msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        return msg;
    },
    new CorrelationData(UUID.randomUUID().toString())
);

6.2.2 消息持久化

  • Exchange、Queue 聲明為 durable = true
  • 消息設(shè)置為 deliveryMode = PERSISTENT
@Bean
public Queue durableQueue() {
    return QueueBuilder.durable("my.queue").build(); // durable=true
}
// 發(fā)送時
MessageProperties props = new MessageProperties();
props.setDeliveryMode(MessageDeliveryMode.PERSISTENT);

?? 即使 RabbitMQ 重啟,持久化消息也不會丟失。

6.2.3 消費者手動 ACK

關(guān)閉自動 ACK,只有業(yè)務(wù)處理成功才確認消息。

@RabbitListener(queues = "my.queue")
public void handleMessage(Message message, Channel channel) throws IOException {
    try {
        // 處理業(yè)務(wù)
        process(message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
        // 根據(jù)策略決定是否 requeue
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
    }
}

6.2.4 死信隊列(DLQ)

處理多次失敗的消息,避免無限重試。

@Bean
public Queue mainQueue() {
    return QueueBuilder.durable("main.queue")
            .withArgument("x-dead-letter-exchange", "dlx.exchange")
            .withArgument("x-dead-letter-routing-key", "dlq.key")
            .withArgument("x-message-ttl", 10000) // 10秒后進 DLQ
            .build();
}
@Bean
public Queue deadLetterQueue() {
    return QueueBuilder.durable("dead.letter.queue").build();
}
@Bean
public DirectExchange deadLetterExchange() {
    return new DirectExchange("dlx.exchange");
}
@Bean
public Binding dlqBinding() {
    return BindingBuilder.bind(deadLetterQueue())
            .to(deadLetterExchange())
            .with("dlq.key");
}

?? 死信隊列詳解:https://www.rabbitmq.com/dlx.html

七、最佳實踐與常見陷阱

7.1 最佳實踐

  • ? 命名規(guī)范:Exchange/Queue 使用 service.event.type 格式(如 order.created
  • ? 冪等性設(shè)計:消費者必須能處理重復(fù)消息(因網(wǎng)絡(luò)重試)
  • ? 監(jiān)控告警:監(jiān)控隊列長度、消費速率、ACK 率
  • ? 資源隔離:不同業(yè)務(wù)使用不同 Virtual Host
  • ? 批量消費:高吞吐場景可考慮批量 ACK(但需權(quán)衡可靠性)

7.2 常見陷阱

  • ? 忘記設(shè)置持久化:Broker 重啟后消息全丟
  • ? 消費者拋異常未處理:導(dǎo)致消息不斷 requeue,CPU 100%
  • ? 隊列無長度限制:突發(fā)流量打爆內(nèi)存
  • ? Routing Key 設(shè)計不合理:導(dǎo)致無法靈活路由
  • ? 過度依賴消息隊列:簡單場景用 REST 更合適

八、結(jié)語

RabbitMQ 作為微服務(wù)架構(gòu)中的“神經(jīng)系統(tǒng)”,在消息推送、服務(wù)解耦、削峰填谷三大場景中發(fā)揮著不可替代的作用。它不僅提升了系統(tǒng)的可伸縮性、可靠性和響應(yīng)速度,還為構(gòu)建松耦合、高內(nèi)聚的分布式系統(tǒng)提供了堅實基礎(chǔ)。

然而,技術(shù)沒有銀彈。合理使用 RabbitMQ 需要深入理解其機制,并結(jié)合業(yè)務(wù)場景權(quán)衡一致性、可用性、性能。希望本文的代碼示例和架構(gòu)圖能為你在實際項目中落地 RabbitMQ 提供清晰的指引。

?? 記住:消息隊列不是萬能的,但沒有消息隊列的微服務(wù)架構(gòu),往往是不完整的。

到此這篇關(guān)于RabbitMQ在微服務(wù)架構(gòu)中的落地:消息推送 / 解耦 / 削峰填谷的文章就介紹到這了,更多相關(guān)RabbitMQ微服務(wù)架構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 通過@Resource注解實現(xiàn)屬性裝配代碼詳解

    通過@Resource注解實現(xiàn)屬性裝配代碼詳解

    這篇文章主要介紹了通過@Resource注解實現(xiàn)屬性裝配代碼詳解,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造

    Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造

    Service Mesh這個“熱”詞是2016年9月被“造”出來,而今年2018年更是被稱為service Mesh的關(guān)鍵之年,各家大公司都希望能在這個思潮下領(lǐng)先一步
    2023-03-03
  • java中4種API參數(shù)傳遞方式統(tǒng)一說明

    java中4種API參數(shù)傳遞方式統(tǒng)一說明

    在Java中,我們可以使用不同的方式來傳遞參數(shù)給方法或函數(shù),這篇文章主要介紹了java中4種API參數(shù)傳遞方式的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-12-12
  • Java多線程之Disruptor入門

    Java多線程之Disruptor入門

    這篇文章主要介紹了Java多線程之Disruptor入門,文中有非常詳細的代碼示例,對正在學(xué)習(xí)java多線程的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java使用SLF4J記錄不同級別日志的示例詳解

    Java使用SLF4J記錄不同級別日志的示例詳解

    SLF4J是一個簡單的日志門面,它允許在運行時選擇不同的日志實現(xiàn),這篇文章主要為大家詳細介紹了如何使用SLF4J記錄不同級別日志,感興趣的可以了解下
    2025-04-04
  • SpringBoot攔截器實現(xiàn)登錄攔截的方法示例

    SpringBoot攔截器實現(xiàn)登錄攔截的方法示例

    這篇文章主要介紹了SpringBoot攔截器實現(xiàn)登錄攔截的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • SpringBoot實現(xiàn)jsonp跨域通信的方法示例

    SpringBoot實現(xiàn)jsonp跨域通信的方法示例

    這篇文章主要介紹了SpringBoot實現(xiàn)jsonp跨域通信的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 使用Java實現(xiàn)KMZ和KML數(shù)據(jù)的直接解析

    使用Java實現(xiàn)KMZ和KML數(shù)據(jù)的直接解析

    本文主要講解如何用JAVA語言,直接解析KMZ數(shù)據(jù),文章首先介紹google地圖中的KMZ和KML數(shù)據(jù),然后使用代碼的方式實現(xiàn)數(shù)據(jù)的解析,最后展示解析成果以及如何將數(shù)據(jù)轉(zhuǎn)換成空間WKT數(shù)據(jù),需要的朋友可以參考下
    2024-06-06
  • Java中圖片轉(zhuǎn)換為Base64的示例及注意事項

    Java中圖片轉(zhuǎn)換為Base64的示例及注意事項

    本文介紹了Base64編碼的概念及其作用,同時列舉了在實現(xiàn)圖片轉(zhuǎn)換為Base64過程中需要注意的問題,包括文件大小、讀取異常、圖片格式、網(wǎng)絡(luò)傳輸效率以及數(shù)據(jù)安全性等,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • springboot返回前端中文亂碼的解決

    springboot返回前端中文亂碼的解決

    這篇文章主要介紹了springboot返回前端中文亂碼的解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評論

莱州市| 潮州市| 霍山县| 伊通| 河间市| 宣武区| 濮阳市| 葵青区| 东辽县| 济源市| 汕尾市| 普定县| 石家庄市| 大同县| 盘山县| 集安市| 郧西县| 凉城县| 南雄市| 喀喇沁旗| 普定县| 广宗县| 正定县| 阳新县| 都兰县| 资中县| 桦川县| 深水埗区| 广安市| 浮梁县| 北川| 营口市| 伊吾县| 绥芬河市| 中阳县| 寿宁县| 兰州市| 行唐县| 临漳县| 沁源县| 德阳市|