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

RabbitMQ 功能詳解與高可靠實(shí)現(xiàn)指南(最新推薦)

 更新時(shí)間:2025年10月08日 10:35:05   作者:?jiǎn)柕里w魚  
本文給大家介紹RabbitMQ功能詳解與高可靠實(shí)現(xiàn)指南,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

RabbitMQ 功能詳解與高可靠實(shí)現(xiàn)指南

一、核心功能概覽

RabbitMQ 提供的主要功能包括:

功能類別核心功能應(yīng)用場(chǎng)景
消息路由交換器路由、綁定規(guī)則復(fù)雜消息分發(fā)
可靠性持久化、確認(rèn)機(jī)制、事務(wù)金融交易、訂單處理
高可用集群、鏡像隊(duì)列關(guān)鍵業(yè)務(wù)系統(tǒng)
擴(kuò)展性插件系統(tǒng)、聯(lián)邦交換器分布式系統(tǒng)
監(jiān)控管理界面、跟蹤功能運(yùn)維監(jiān)控
安全TLS、權(quán)限控制企業(yè)級(jí)應(yīng)用

二、完整配置與代碼實(shí)現(xiàn)

2.1 基礎(chǔ)配置

# application.yml
spring:
  rabbitmq:
    host: rabbitmq-prod.example.com
    port: 5671 # AMQPS端口
    username: app-user
    password: secure-password
    virtual-host: /app-vhost
    connection-timeout: 5000
    # TLS/SSL 配置
    ssl:
      enabled: true
      algorithm: TLSv1.2
      key-store: classpath:keystore.jks
      key-store-password: keystore-pass
      trust-store: classpath:truststore.jks
      trust-store-password: truststore-pass
    # 高可靠性配置
    publisher-confirm-type: correlated # 發(fā)布者確認(rèn)
    publisher-returns: true # 返回回調(diào)
    template:
      mandatory: true # 強(qiáng)制路由檢查
    # 消費(fèi)者配置
    listener:
      type: simple
      simple:
        acknowledge-mode: manual # 手動(dòng)確認(rèn)
        concurrency: 5 # 最小并發(fā)
        max-concurrency: 20 # 最大并發(fā)
        prefetch: 10 # 預(yù)取數(shù)量
        retry:
          enabled: true
          max-attempts: 3
          initial-interval: 1000

2.2 認(rèn)證與安全實(shí)現(xiàn)

// 安全連接工廠配置
@Bean
public ConnectionFactory secureConnectionFactory(
        @Value("${spring.rabbitmq.host}") String host,
        @Value("${spring.rabbitmq.port}") int port,
        @Value("${spring.rabbitmq.username}") String username,
        @Value("${spring.rabbitmq.password}") String password,
        @Value("${spring.rabbitmq.virtual-host}") String vhost) throws Exception {
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(
        loadKeyManagerFactory("keystore.jks", "keystore-pass"),
        loadTrustManagerFactory("truststore.jks", "truststore-pass"),
        new SecureRandom()
    );
    CachingConnectionFactory factory = new CachingConnectionFactory();
    factory.setHost(host);
    factory.setPort(port);
    factory.setVirtualHost(vhost);
    factory.setUsername(username);
    factory.setPassword(password);
    factory.setConnectionTimeout(5000);
    // 配置SSL
    factory.getRabbitConnectionFactory().useSslProtocol(sslContext);
    return factory;
}
private KeyManager[] loadKeyManagerFactory(String keystore, String password) throws Exception {
    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(getClass().getResourceAsStream(keystore), password.toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, password.toCharArray());
    return kmf.getKeyManagers();
}
private TrustManager[] loadTrustManagerFactory(String truststore, String password) throws Exception {
    KeyStore ts = KeyStore.getInstance("JKS");
    ts.load(getClass().getResourceAsStream(truststore), password.toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ts);
    return tmf.getTrustManagers();
}

三、高可靠性實(shí)現(xiàn)

3.1 消息持久化與確認(rèn)

// 持久化隊(duì)列配置
@Configuration
public class ReliableMessagingConfig {
    @Bean
    public Queue persistentQueue() {
        return QueueBuilder.durable("persistent.queue")
            .withArgument("x-message-ttl", 60000) // 60秒TTL
            .withArgument("x-dead-letter-exchange", "dlx.exchange") // 死信交換器
            .build();
    }
    @Bean
    public DirectExchange persistentExchange() {
        return new DirectExchange("persistent.exchange", true, false); // 持久化交換器
    }
    @Bean
    public Binding persistentBinding() {
        return BindingBuilder.bind(persistentQueue())
            .to(persistentExchange())
            .with("persistent.routing.key");
    }
}
// 生產(chǎn)者確認(rèn)回調(diào)
@Bean
public RabbitTemplate reliableRabbitTemplate(ConnectionFactory connectionFactory) {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    template.setMessageConverter(new Jackson2JsonMessageConverter());
    // 確認(rèn)回調(diào)
    template.setConfirmCallback((correlationData, ack, cause) -> {
        if (ack) {
            log.info("消息發(fā)送成功: {}", correlationData.getId());
        } else {
            log.error("消息發(fā)送失敗: {}, 原因: {}", correlationData.getId(), cause);
            // 重試或記錄失敗消息
            messageRetryService.retryMessage(correlationData);
        }
    });
    // 返回回調(diào)
    template.setReturnsCallback(returned -> {
        log.error("消息路由失敗: {}, 返回信息: {}", 
            new String(returned.getMessage().getBody()), 
            returned.getReplyText());
        // 處理無法路由的消息
        deadLetterService.handleUnroutableMessage(returned);
    });
    return template;
}
// 消費(fèi)者手動(dòng)確認(rèn)
@Component
@Slf4j
public class ReliableConsumer {
    @RabbitListener(queues = "persistent.queue")
    public void handleMessage(OrderMessage order, Channel channel, 
            @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            // 處理業(yè)務(wù)邏輯
            orderService.processOrder(order);
            // 成功處理,確認(rèn)消息
            channel.basicAck(deliveryTag, false);
            log.info("訂單處理成功: {}", order.getOrderId());
        } catch (BusinessException ex) {
            // 業(yè)務(wù)異常,記錄日志并拒絕消息(不重新入隊(duì))
            log.error("訂單處理失敗: {}, 原因: {}", order.getOrderId(), ex.getMessage());
            channel.basicReject(deliveryTag, false);
        } catch (Exception ex) {
            // 系統(tǒng)異常,拒絕消息并重新入隊(duì)
            log.error("系統(tǒng)錯(cuò)誤處理訂單: {}, 原因: {}", order.getOrderId(), ex.getMessage());
            channel.basicReject(deliveryTag, true);
        }
    }
}

3.2 死信隊(duì)列與重試機(jī)制

// 死信隊(duì)列配置
@Configuration
public class DeadLetterConfig {
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange("dlx.exchange", true, false);
    }
    @Bean
    public Queue dlQueue() {
        return QueueBuilder.durable("dl.queue").build();
    }
    @Bean
    public Binding dlBinding() {
        return BindingBuilder.bind(dlQueue())
            .to(dlxExchange())
            .with("dl.routing.key");
    }
}
// 死信處理器
@Component
@Slf4j
public class DeadLetterHandler {
    @RabbitListener(queues = "dl.queue")
    public void handleDeadLetter(Message message, Channel channel,
            @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            // 解析原始消息
            OrderMessage order = parseOriginalMessage(message);
            // 記錄死信信息
            log.warn("收到死信消息: {}, 原始路由: {}, 原因: {}", 
                order.getOrderId(),
                message.getMessageProperties().getReceivedRoutingKey(),
                message.getMessageProperties().getDeathHeader("reason"));
            // 處理死信(記錄日志、發(fā)送警報(bào)等)
            deadLetterService.processDeadLetter(order);
            // 確認(rèn)死信消息
            channel.basicAck(deliveryTag, false);
        } catch (Exception ex) {
            log.error("處理死信失敗", ex);
            // 死信處理失敗,拒絕并重新入隊(duì)
            channel.basicReject(deliveryTag, true);
        }
    }
    private OrderMessage parseOriginalMessage(Message message) {
        // 從死信消息中提取原始消息
        Message original = (Message) message.getMessageProperties()
            .getHeaders().get("x-death").get(0).get("original-message");
        return (OrderMessage) new Jackson2JsonMessageConverter()
            .fromMessage(original, OrderMessage.class);
    }
}
// 重試機(jī)制實(shí)現(xiàn)
@Service
@Slf4j
public class MessageRetryService {
    private final RabbitTemplate rabbitTemplate;
    public void retryMessage(CorrelationData correlationData) {
        Message message = correlationData.getReturned().getMessage();
        int retryCount = getRetryCount(message);
        if (retryCount < 3) {
            // 指數(shù)退避重試
            long delay = (long) Math.pow(2, retryCount) * 1000;
            log.info("消息重試 {}: 延遲 {}ms", correlationData.getId(), delay);
            // 延遲重試
            rabbitTemplate.convertAndSend(
                "retry.exchange",
                "retry.routing.key",
                message,
                m -> {
                    m.getMessageProperties().setDelay((int) delay);
                    m.getMessageProperties().setHeader("retry-count", retryCount + 1);
                    return m;
                }
            );
        } else {
            // 超過重試次數(shù),轉(zhuǎn)為死信
            log.error("消息重試超過最大次數(shù): {}", correlationData.getId());
            deadLetterService.handleMaxRetryExceeded(message);
        }
    }
    private int getRetryCount(Message message) {
        return message.getMessageProperties()
            .getHeader("retry-count") != null ? 
            (int) message.getMessageProperties().getHeader("retry-count") : 0;
    }
}

四、高可用集群配置

4.1 集群配置

// 集群連接工廠
@Bean
public CachingConnectionFactory clusterConnectionFactory() {
    ConnectionFactory rabbitConnectionFactory = new ConnectionFactory();
    // 設(shè)置集群節(jié)點(diǎn)
    Address[] addresses = {
        new Address("rabbitmq-node1", 5672),
        new Address("rabbitmq-node2", 5672),
        new Address("rabbitmq-node3", 5672)
    };
    rabbitConnectionFactory.setUsername("cluster-user");
    rabbitConnectionFactory.setPassword("cluster-password");
    rabbitConnectionFactory.setVirtualHost("/cluster-vhost");
    // 集群連接工廠
    return new CachingConnectionFactory(
        new CompositeConnectionFactory(addresses, rabbitConnectionFactory)
    );
}
// 鏡像隊(duì)列配置
@Bean
public Queue mirroredQueue() {
    Map<String, Object> args = new HashMap<>();
    args.put("x-ha-policy", "all"); // 鏡像到所有節(jié)點(diǎn)
    return new Queue("mirrored.queue", true, false, false, args);
}

4.2 聯(lián)邦交換器(跨集群)

// 聯(lián)邦交換器配置
@Bean
public Exchange federatedExchange() {
    Map<String, Object> args = new HashMap<>();
    args.put("federation-upstream", "upstream-cluster");
    return new DirectExchange("federated.exchange", true, false, args);
}
// 上游集群配置
@Bean
public ConnectionFactory upstreamConnectionFactory() {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("upstream-rabbitmq");
    factory.setUsername("federation-user");
    factory.setPassword("federation-pass");
    return factory;
}
@Bean
public RabbitAdmin upstreamAdmin() {
    return new RabbitAdmin(upstreamConnectionFactory());
}
@Bean
public FederationExchange federationUpstream() {
    Map<String, Object> args = new HashMap<>();
    args.put("uri", "amqp://federation-user:federation-pass@upstream-rabbitmq:5672");
    args.put("expires", 3600000); // 1小時(shí)
    return new FederationExchange("upstream-cluster", args);
}

五、異常處理與監(jiān)控

5.1 全局異常處理

// 自定義異常處理策略
public class CustomErrorStrategy extends ConditionalRejectingErrorHandler {
    public CustomErrorStrategy() {
        super(new CustomExceptionStrategy());
    }
    private static class CustomExceptionStrategy implements ConditionalRejectingErrorHandler.ExceptionStrategy {
        @Override
        public boolean isFatal(Throwable t) {
            // 業(yè)務(wù)異常不致命,重新入隊(duì)
            if (t.getCause() instanceof BusinessException) {
                return false;
            }
            // 系統(tǒng)異常致命,拒絕消息
            return true;
        }
    }
}
// 配置容器工廠
@Bean
public SimpleRabbitListenerContainerFactory robustContainerFactory(
        ConnectionFactory connectionFactory, 
        MessageRecoverer messageRecoverer) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    factory.setPrefetchCount(10);
    // 自定義異常處理
    factory.setErrorHandler(new CustomErrorStrategy());
    // 重試策略
    RetryInterceptorBuilder<?, ?> retry = RetryInterceptorBuilder.stateless()
        .maxAttempts(3)
        .backOffOptions(1000, 2.0, 10000);
    factory.setAdviceChain(retry.build());
    // 消息恢復(fù)器
    factory.setRecoveryBackOff(new FixedBackOff(5000, 3)); // 5秒間隔,最多3次
    factory.setMessageRecoverer(messageRecoverer);
    return factory;
}
// 消息恢復(fù)器(重試失敗后處理)
@Bean
public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate) {
    return new RepublishMessageRecoverer(rabbitTemplate, "error.exchange", "error.routing.key");
}

5.2 監(jiān)控與跟蹤

// 消息跟蹤配置
@Configuration
@EnableRabbit
public class TracingConfig implements RabbitListenerConfigurer {
    @Bean
    public Tracer tracer() {
        return new BraveTracer();
    }
    @Bean
    public BraveRabbitTemplateAspect rabbitTemplateAspect(Tracer tracer) {
        return new BraveRabbitTemplateAspect(tracer);
    }
    @Bean
    public BraveRabbitListenerAspect rabbitListenerAspect(Tracer tracer) {
        return new BraveRabbitListenerAspect(tracer);
    }
    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
        registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
    }
    @Bean
    public MessageHandlerMethodFactory messageHandlerMethodFactory() {
        DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        return factory;
    }
}
// 指標(biāo)監(jiān)控
@Bean
public MeterRegistryCustomizer<MeterRegistry> rabbitMetrics() {
    return registry -> {
        new RabbitMQMetrics(connectionFactory()).bindTo(registry);
    };
}

六、安全最佳實(shí)踐

6.1 權(quán)限控制

// 權(quán)限配置服務(wù)
@Service
public class RabbitPermissionService {
    private final RabbitAdmin rabbitAdmin;
    public void configurePermissions(String username) {
        // 配置用戶權(quán)限
        Permission permission = new Permission(
            "/", // 虛擬主機(jī)
            "app-.*", // 配置權(quán)限正則
            "app-.*", // 寫權(quán)限正則
            "app-.*"  // 讀權(quán)限正則
        );
        rabbitAdmin.declareBinding(new Binding(
            "", // 空表示默認(rèn)交換器
            Binding.DestinationType.QUEUE,
            "permission.exchange",
            "permission.routing.key",
            null
        ));
        rabbitAdmin.getRabbitTemplate().invoke(channel -> {
            channel.queueBind("permission.queue", "permission.exchange", "permission.routing.key");
            return null;
        });
    }
}

6.2 審計(jì)日志

// 審計(jì)攔截器
@Bean
public ChannelInterceptor auditInterceptor() {
    return new ChannelInterceptorAdapter() {
        @Override
        public void afterSendCompletion(Message<?> message, MessageChannel channel, 
                boolean sent, Exception ex) {
            if (sent) {
                auditService.logMessageSent(
                    message.getHeaders().getId(),
                    message.getPayload().getClass().getSimpleName(),
                    message.getHeaders().get("routingKey", String.class)
                );
            }
        }
        @Override
        public void afterReceiveCompletion(Message<?> message, MessageChannel channel, 
                Exception ex) {
            if (ex == null) {
                auditService.logMessageReceived(
                    message.getHeaders().getId(),
                    message.getPayload().getClass().getSimpleName(),
                    message.getHeaders().get("routingKey", String.class)
                );
            }
        }
    };
}

七、完整生產(chǎn)示例

7.1 訂單處理系統(tǒng)

// 訂單消息
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderMessage {
    private String orderId;
    private String customerId;
    private BigDecimal amount;
    private List<OrderItem> items;
    private LocalDateTime timestamp;
}
// 訂單生產(chǎn)者
@Service
@RequiredArgsConstructor
public class OrderProducer {
    private final RabbitTemplate rabbitTemplate;
    public void placeOrder(Order order) {
        OrderMessage message = convertToMessage(order);
        CorrelationData correlationData = new CorrelationData(order.getId());
        rabbitTemplate.convertAndSend(
            "order.exchange",
            "order.placed",
            message,
            m -> {
                // 設(shè)置持久化
                m.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                // 設(shè)置消息ID
                m.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                return m;
            },
            correlationData
        );
    }
}
// 訂單消費(fèi)者
@Component
@Slf4j
public class OrderConsumer {
    @RabbitListener(
        queues = "order.queue",
        containerFactory = "robustContainerFactory"
    )
    public void processOrder(OrderMessage order, Channel channel,
            @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            // 處理訂單
            orderService.process(order);
            // 發(fā)送訂單確認(rèn)
            eventPublisher.publishOrderConfirmed(order.getOrderId());
            // 確認(rèn)消息
            channel.basicAck(deliveryTag, false);
        } catch (InventoryException ex) {
            // 庫存不足,延遲重試
            log.warn("庫存不足,延遲重試: {}", order.getOrderId());
            channel.basicReject(deliveryTag, false);
            retryService.retryOrder(order, 30000); // 30秒后重試
        } catch (PaymentException ex) {
            // 支付失敗,轉(zhuǎn)為死信
            log.error("支付失敗: {}", order.getOrderId());
            channel.basicReject(deliveryTag, false);
        }
    }
}
// 死信處理器
@Component
public class OrderDeadLetterHandler {
    @RabbitListener(queues = "dl.order.queue")
    public void handleDeadOrder(OrderMessage order) {
        log.error("收到死信訂單: {}", order.getOrderId());
        // 通知客服系統(tǒng)
        customerService.notifyFailedOrder(order);
        // 記錄到數(shù)據(jù)庫
        deadOrderRepository.save(order);
    }
}

八、最佳實(shí)踐總結(jié)

8.1 可靠性保證矩陣

場(chǎng)景解決方案實(shí)現(xiàn)方式
消息丟失持久化 + 確認(rèn)機(jī)制隊(duì)列/消息持久化 + 發(fā)布者確認(rèn)
消息重復(fù)冪等處理唯一消息ID + 業(yè)務(wù)校驗(yàn)
消息積壓限流 + 擴(kuò)容預(yù)取值控制 + 動(dòng)態(tài)消費(fèi)者
節(jié)點(diǎn)故障集群 + 鏡像隊(duì)列RabbitMQ集群 + HA策略
網(wǎng)絡(luò)分區(qū)自動(dòng)恢復(fù)策略網(wǎng)絡(luò)檢測(cè) + 自動(dòng)恢復(fù)
安全威脅TLS + 權(quán)限控制SSL加密 + 細(xì)粒度權(quán)限

8.2 性能優(yōu)化建議

  1. 連接管理

    • 使用連接池(CachingConnectionFactory)
    • 復(fù)用信道(Channel pooling)
  2. 批處理

    • 批量發(fā)送消息
    • 批量確認(rèn)消息
  3. 壓縮

    • 對(duì)大消息進(jìn)行壓縮
    • 使用高效壓縮算法(LZ4)
  4. 序列化

    • 使用高效序列化(Protobuf, Avro)
    • 避免Java原生序列化
  5. 資源監(jiān)控

    • 設(shè)置隊(duì)列長(zhǎng)度限制
    • 監(jiān)控內(nèi)存和磁盤使用

通過以上實(shí)現(xiàn),RabbitMQ 可以在企業(yè)級(jí)應(yīng)用中提供高可靠、高可用的消息服務(wù),滿足各種復(fù)雜業(yè)務(wù)場(chǎng)景的需求。

相關(guān)文獻(xiàn)

【分布式中間件】幾個(gè)常用的消息中間件
【分布式技術(shù)】深入理解AMQP(高級(jí)消息隊(duì)列協(xié)議)

到此這篇關(guān)于RabbitMQ 功能詳解與高可靠實(shí)現(xiàn)指南的文章就介紹到這了,更多相關(guān)RabbitMQ 高可靠?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java報(bào)錯(cuò)net.dean.jraw.http.NetworkException異常的原因及解決方法

    Java報(bào)錯(cuò)net.dean.jraw.http.NetworkException異常的原因及解決方法

    在開發(fā)涉及網(wǎng)絡(luò)通信的Java應(yīng)用程序時(shí),我們經(jīng)常需要處理各種網(wǎng)絡(luò)異常,net.dean.jraw.http.NetworkException是在使用jRAW庫時(shí)可能遇到的一個(gè)異常,本文將詳細(xì)探討NetworkException的成因,并提供多種解決方案,需要的朋友可以參考下
    2024-12-12
  • JAVA破壞單例模式的方式以及避免方法

    JAVA破壞單例模式的方式以及避免方法

    這篇文章主要介紹了JAVA破壞單例模式的方式以及避免方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 解析JavaSe的抽象類和接口

    解析JavaSe的抽象類和接口

    這篇文章主要為大家詳細(xì)介紹了JavaSe的抽象類和接口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • SpringMVC多個(gè)模塊404報(bào)錯(cuò)問題及解決

    SpringMVC多個(gè)模塊404報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了SpringMVC多個(gè)模塊404報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 聊聊Mybatis中sql語句不等于的表示

    聊聊Mybatis中sql語句不等于的表示

    這篇文章主要介紹了Mybatis中sql語句不等于的表示方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2021-07-07
  • Java實(shí)現(xiàn)添加、驗(yàn)證PDF數(shù)字簽名的方法示例

    Java實(shí)現(xiàn)添加、驗(yàn)證PDF數(shù)字簽名的方法示例

    在設(shè)置文檔內(nèi)容保護(hù)的方法中,除了對(duì)文檔加密、添加水印外,應(yīng)用數(shù)字簽名也是一種有效防偽手段。本文就使用Java實(shí)現(xiàn)添加、驗(yàn)證PDF數(shù)字簽名,感興趣的可以了解一下
    2021-07-07
  • Java中的jinfo命令使用詳解

    Java中的jinfo命令使用詳解

    jinfo是JDK提供的一個(gè)可以實(shí)時(shí)查看Java虛擬機(jī)各種配置參數(shù)和系統(tǒng)屬性的命令行工具,本文給大家介紹下Java中的jinfo命令使用,感興趣的朋友一起看看吧
    2022-03-03
  • 解析spring-security權(quán)限控制和校驗(yàn)的問題

    解析spring-security權(quán)限控制和校驗(yàn)的問題

    這篇文章主要介紹了解析spring-security權(quán)限控制和校驗(yàn)的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Java設(shè)計(jì)模式之裝飾器模式

    Java設(shè)計(jì)模式之裝飾器模式

    這篇文章介紹了Java設(shè)計(jì)模式之裝飾器模式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Java中的Fork/Join框架使用詳解

    Java中的Fork/Join框架使用詳解

    這篇文章主要介紹了Java中的Fork/Join框架使用詳解,Fork/Join?框架:就是在必要的情況下,將一個(gè)大任務(wù),進(jìn)行<BR>拆分(fork)成若干個(gè)小任務(wù)(拆到不可再拆時(shí)),再將一個(gè)個(gè)<BR>的小任務(wù)運(yùn)算的結(jié)果進(jìn)行?join?匯總,需要的朋友可以參考下
    2024-01-01

最新評(píng)論

新兴县| 贵南县| 巴林左旗| 杂多县| 萝北县| 南陵县| 中江县| 壤塘县| 静宁县| 页游| 安达市| 延寿县| 家居| 青铜峡市| 资阳市| 临沭县| 西城区| 江川县| 上高县| 环江| 大渡口区| 岳阳县| 三门县| 曲松县| 梨树县| 宜宾县| 镇江市| 庄浪县| 沈阳市| 贵港市| 新密市| 牟定县| 临江市| 驻马店市| 宽城| 北安市| 赤壁市| 仙居县| 钟山县| 四平市| 成武县|