精华内容
下载资源
问答
  • 政务区块链电子证照应用场景

    万次阅读 2020-08-09 10:14:35
    政务区块链对于电子证照共享的应用场景 区块链电子证照系统场景,所解决的是证照共享的问题。 在预防各部门自己的证照被批量的被盗用或被篡改。采用区块链证照模式,将各个部门的证照共享。 解决的问题 证件被...

    政务区块链对于电子证照共享的应用场景

    区块链电子证照系统场景,所解决的是证照共享的问题。

    在预防各部门自己的证照被批量的被盗用或被篡改。采用区块链证照模式,将各个部门的证照共享。

    解决的问题

    证件被批量盗取

    证件被他方恶意修改

    证件共享难

     

    实现模式

    各个部门将证件的哈希值、关联主键(身份证等)、获取地址、摘要保存到区块链中,通过区块链同步到各个部门。

    在各个部门中如果需要用到证照信息,通过关联主键获取单张证件。

     

     

     

    电子证明共享的应用场景

     

    通过构建政务区块链电子证照共享平台,以解决以上的难题。

     

          先来描述一个场景,当A部门需要提供给B部门证明,用以证明办证人员的有效性来说。来B部门办证的人员选要去A部门开具有效证明。然后那这A部门开具的纸质盖章证明来B部门办证。

    通过以上场景会出现几种问题:

    证明丢失

    证明作假

    证明格式不正确

    证明无效

    那么上了政务区块链以后会发生什么变化呢?

    1、场景一 二维码哈希值确认证明

              从上图看出办事人员的操作步骤并没有减少,但是其中一个无纸化和防丢失优化的整个办证的流程。

     2、场景二 网上申请开具证明,部门之间自动同步。

    从上述场景优化出第二个场景。

                在新的过程中,需办证人员值需要在B部门等待办理,并不需要去A部门多跑一趟。

    3、场景三 证明验证和历史证明追溯

    在某种情况下,B部门办理了有效证件,但是在办理过程中其实没有拿到A部门的证明。或者B部门因为办理某个有效证件并没保存A部门的证明。

    在以上情况下,两个部门都无法追溯这个事情的具体真想。那么通过调用区块链中的历史记录就可以还原整个事情的过程。

    展开全文
  • SpringBoot整合RabbitMQ之 典型应用场景实战一

    万次阅读 多人点赞 2018-10-09 15:08:04
    特别是在一些典型的应用场景以及业务模块中具有重要的作用,比如业务服务模块解耦、异步通信、高并发限流、超时业务、数据延迟处理等。 其中课程的学习链接地址:https://edu.csdn.net/course/detail/9314 ...

    实战前言

    RabbitMQ 作为目前应用相当广泛的消息中间件,在企业级应用、微服务应用中充当着重要的角色。特别是在一些典型的应用场景以及业务模块中具有重要的作用,比如业务服务模块解耦、异步通信、高并发限流、超时业务、数据延迟处理等。

    其中课程的学习链接地址:https://edu.csdn.net/course/detail/9314 

    RabbitMQ 官网拜读

    首先,让我们先拜读 RabbitMQ 官网的技术开发手册以及相关的 Features,感兴趣的朋友可以耐心的阅读其中的相关介绍,相信会有一定的收获,地址可见:

    http://www.rabbitmq.com/getstarted.html

    阅读该手册过程中,我们可以得知 RabbitMQ 其实核心就是围绕 “消息模型” 来展开的,其中就包括了组成消息模型的相关组件:生产者,消费者,队列,交换机,路由,消息等!而我们在实战应用中,实际上也是紧紧围绕着 “消息模型” 来展开撸码的!

    下面,我就介绍一下这一消息模型的演变历程,当然,这一历程在 RabbitMQ 官网也是可以窥览得到的!

    enter image description here

    enter image description here

    enter image description here

    上面几个图就已经概述了几个要点,而且,这几个要点的含义可以说是字如其名!

    1. 生产者:发送消息的程序
    2. 消费者:监听接收消费消息的程序
    3. 消息:一串二进制数据流
    4. 队列:消息的暂存区/存储区
    5. 交换机:消息的中转站,用于接收分发消息。其中有 fanout、direct、topic、headers 四种
    6. 路由:相当于密钥/第三者,与交换机绑定即可路由消息到指定的队列!

    正如上图所展示的消息模型的演变,接下来我们将以代码的形式实战各种典型的业务场景!

    SpringBoot 整合 RabbitMQ 实战

    工欲善其事,必先利其器。我们首先需要借助 IDEA 的 Spring Initializr 用 Maven 构建一个 SpringBoot 的项目,并引入 RabbitMQ、Mybatis、Log4j 等第三方框架的依赖。搭建完成之后,可以简单的写个 RabbitMQController 测试一下项目是否搭建是否成功(可以暂时用单模块方式构建)

    紧接着,我们进入实战的核心阶段,在项目或者服务中使用 RabbitMQ,其实无非是有几个核心要点要牢牢把握住,这几个核心要点在撸码过程中需要“时刻的游荡在自己的脑海里”,其中包括:

    1. 我要发送的消息是什么
    2. 我应该需要创建什么样的消息模型:DirectExchange+RoutingKey?TopicExchange+RoutingKey?等
    3. 我要处理的消息是实时的还是需要延时/延迟的?
    4. 消息的生产者需要在哪里写,消息的监听消费者需要在哪里写,各自的处理逻辑是啥

    基于这样的几个要点,我们先小试牛刀一番,采用 RabbitMQ 实战异步写日志与异步发邮件。当然啦,在进行实战前,我们需要安装好 RabbitMQ 及其后端控制台应用,并在项目中配置一下 RabbitMQ 的相关参数以及相关 Bean 组件。

    RabbitMQ 安装完成后,打开后端控制台应用:http://localhost:15672  输入guest guest 登录,看到下图即表示安装成功

    enter image description here

    然后是项目配置文件层面的配置 application.properties

    spring.rabbitmq.host=127.0.0.1
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=guest
    spring.rabbitmq.password=guest
    spring.rabbitmq.listener.concurrency=10
    spring.rabbitmq.listener.max-concurrency=20
    spring.rabbitmq.listener.prefetch=5

    其中,后面三个参数主要是用于“并发量的配置”,表示:并发消费者的初始化值,并发消费者的最大值,每个消费者每次监听时可拉取处理的消息数量。

    接下来,我们需要以 Configuration 的方式配置 RabbitMQ 并以 Bean 的方式显示注入 RabbitMQ 在发送接收处理消息时相关 Bean 组件配置其中典型的配置是 RabbitTemplate 以及 SimpleRabbitListenerContainerFactory,前者是充当消息的发送组件,后者是用于管理  RabbitMQ监听器listener 的容器工厂,其代码如下:

    @Configuration
        public class RabbitmqConfig {
        private static final Logger log= LoggerFactory.getLogger(RabbitmqConfig.class);
    
        @Autowired
        private Environment env;
    
        @Autowired
        private CachingConnectionFactory connectionFactory;
    
        @Autowired
        private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;
    
        /**
         * 单一消费者
         * @return
         */
        @Bean(name = "singleListenerContainer")
        public SimpleRabbitListenerContainerFactory listenerContainer(){
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            factory.setConnectionFactory(connectionFactory);
            factory.setMessageConverter(new Jackson2JsonMessageConverter());
            factory.setConcurrentConsumers(1);
            factory.setMaxConcurrentConsumers(1);
            factory.setPrefetchCount(1);
            factory.setTxSize(1);
            factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
            return factory;
        }
    
        /**
         * 多个消费者
         * @return
         */
        @Bean(name = "multiListenerContainer")
        public SimpleRabbitListenerContainerFactory multiListenerContainer(){
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            factoryConfigurer.configure(factory,connectionFactory);
            factory.setMessageConverter(new Jackson2JsonMessageConverter());
            factory.setAcknowledgeMode(AcknowledgeMode.NONE);
            factory.setConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.concurrency",int.class));
            factory.setMaxConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.max-concurrency",int.class));
            factory.setPrefetchCount(env.getProperty("spring.rabbitmq.listener.prefetch",int.class));
            return factory;
        }
    
        @Bean
        public RabbitTemplate rabbitTemplate(){
            connectionFactory.setPublisherConfirms(true);
            connectionFactory.setPublisherReturns(true);
            RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
            rabbitTemplate.setMandatory(true);
            rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
                @Override
                public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                    log.info("消息发送成功:correlationData({}),ack({}),cause({})",correlationData,ack,cause);
                }
            });
            rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
                @Override
                public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                    log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}",exchange,routingKey,replyCode,replyText,message);
                }
            });
            return rabbitTemplate;
        }}

    RabbitMQ 实战:业务模块解耦以及异步通信

    在一些企业级系统中,我们经常可以见到一个执行 function 通常是由许多子模块组成的,这个 function 在执行过程中,需要 同步的将其代码从头开始执行到尾,即执行流程是 module_A -> module_B -> module_C -> module_D,典型的案例可以参见汇编或者 C 语言等面向过程语言开发的应用,现在的一些 JavaWeb 应用也存在着这样的写法。

    而我们知道,这个执行流程其实对于整个 function 来讲是有一定的弊端的,主要有几点:

    1. 整个 function 的执行响应时间将很久;
    2. 如果某个 module 发生异常而没有处理得当,可能会影响其他 module 甚至整个 function 的执行流程与结果;
    3. 整个 function 中代码可能会很冗长,模块与模块之间可能需要进行强通信以及数据的交互,出现问题时难以定位与维护,甚至会陷入 “改一处代码而动全身”的尴尬境地!

    故而,我们需要想办法进行优化,我们需要将强关联的业务模块解耦以及某些模块之间实行异步通信!下面就以两个场景来实战我们的优化措施!

    场景一:异步记录用户操作日志

    对于企业级应用系统或者微服务应用中,我们经常需要追溯跟踪记录用户的操作日志,而这部分的业务在某种程度上是不应该跟主业务模块耦合在一起的,故而我们需要将其单独抽出并以异步的方式与主模块进行异步通信交互数据。

    下面我们就用 RabbitMQ 的 DirectExchange+RoutingKey 消息模型也实现“用户登录成功记录日志”的场景。如前面所言,我们需要在脑海里回荡着几个要点:

    • 消息模型:DirectExchange+RoutingKey 消息模型
    • 消息:用户登录的实体信息,包括用户名,登录事件,来源的IP,所属日志模块等信息
    • 发送接收:在登录的 Controller 中实现发送,在某个 listener 中实现接收并将监听消费到的消息入数据表;实时发送接收

    首先我们需要在上面的 RabbitmqConfig 类中创建消息模型:包括 Queue、Exchange、RoutingKey 等的建立,代码如下:

    enter image description here

    上图中 env 获取的信息,我们需要在 application.properties 进行配置,其中 mq.env=local

    enter image description here

    此时,我们将整个项目/服务跑起来,并打开 RabbitMQ 后端控制台应用,即可看到队列以及交换机及其绑定已经建立好了,如下所示:

    enter image description here

    enter image description here

    接下来,我们需要在 Controller 中执行用户登录逻辑,记录用户登录日志,查询获取用户角色视野资源信息等,由于篇幅关系,在这里我们重点要实现的是用MQ实现 “异步记录用户登录日志” 的逻辑,即在这里 Controller 将充当“生产者”的角色,核心代码如下:

    @RestController
        public class UserController {
    
        private static final Logger log= LoggerFactory.getLogger(HelloWorldController.class);
    
        private static final String Prefix="user";
    
        @Autowired
        private ObjectMapper objectMapper;
    
        @Autowired
        private UserMapper userMapper;
    
        @Autowired
        private UserLogMapper userLogMapper;
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        @Autowired
        private Environment env;
    
        @RequestMapping(value = Prefix+"/login",method = RequestMethod.POST,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
        public BaseResponse login(@RequestParam("userName") String userName,@RequestParam("password") String password){
            BaseResponse response=new BaseResponse(StatusCode.Success);
            try {
                //TODO:执行登录逻辑
                User user=userMapper.selectByUserNamePassword(userName,password);
                if (user!=null){
                    //TODO:异步写用户日志
                    try {
                        UserLog userLog=new UserLog(userName,"Login","login",objectMapper.writeValueAsString(user));
                        userLog.setCreateTime(new Date());
                        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                        rabbitTemplate.setExchange(env.getProperty("log.user.exchange.name"));
                        rabbitTemplate.setRoutingKey(env.getProperty("log.user.routing.key.name"));
    
                        Message message=MessageBuilder.withBody(objectMapper.writeValueAsBytes(userLog)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
                        message.getMessageProperties().setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, MessageProperties.CONTENT_TYPE_JSON); 
                        rabbitTemplate.convertAndSend(message);         
                    }catch (Exception e){
                        e.printStackTrace();
                    }
    
                    //TODO:塞权限数据-资源数据-视野数据
                }else{
                    response=new BaseResponse(StatusCode.Fail);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            return response;
        }}

    在上面的“发送逻辑”代码中,其实也体现了我们最开始介绍的演进中的几种消息模型,比如我们是将消息发送到 Exchange 的而不是 Queue,消息是以二进制流的形式进行传输等等。当用 postman 请求到这个 controller 的方法时,我们可以在 RabbitMQ 的后端控制台应用看到一条未确认的消息,通过 GetMessage 即可看到其中的详情,如下:

    enter image description here

    最后,我们将开发消费端的业务代码,如下:

     @Component
        public class CommonMqListener {
    
        private static final Logger log= LoggerFactory.getLogger(CommonMqListener.class);
    
        @Autowired
        private ObjectMapper objectMapper;
    
        @Autowired
        private UserLogMapper userLogMapper;
    
        @Autowired
        private MailService mailService;
    
        /**
         * 监听消费用户日志
         * @param message
         */
        @RabbitListener(queues = "${log.user.queue.name}",containerFactory = "singleListenerContainer")
        public void consumeUserLogQueue(@Payload byte[] message){
            try {
                UserLog userLog=objectMapper.readValue(message, UserLog.class);
                log.info("监听消费用户日志 监听到消息: {} ",userLog);
                //TODO:记录日志入数据表
                userLogMapper.insertSelective(userLog);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    将服务跑起来之后,我们即可监听消费到上面 Queue 中的消息,即当前用户登录的信息,而且,我们也可以看到“记录用户登录日志”的逻辑是由一条异于主业务线程的异步线程去执行的:

    enter image description here

    “异步记录用户操作日志”的案例我想足以用于诠释上面所讲的相关理论知识点了,在后续篇章中,由于篇幅限制,我将重点介绍其核心的业务逻辑!

    场景二:异步发送邮件

    发送邮件的场景,其实也是比较常见的,比如用户注册需要邮箱验证,用户异地登录发送邮件通知等等,在这里我以 RabbitMQ 实现异步发送邮件。实现的步骤跟场景一几乎一致!

    1. 消息模型的创建

    enter image description here

    2. 配置信息的创建

    enter image description here

    3. 生产端

    enter image description here

    4. 消费端

    enter image description here

    RabbitMQ 实战:并发量配置与消息确认机制

    实战背景

    对于消息模型中的 listener 而言,默认情况下是“单消费实例”的配置,即“一个 listener 对应一个消费者”,这种配置对于上面所讲的“异步记录用户操作日志”、“异步发送邮件”等并发量不高的场景下是适用的。但是在对于秒杀系统、商城抢单等场景下可能会显得很吃力!

    我们都知道,秒杀系统跟商城抢单均有一个共同的明显的特征,即在某个时刻会有成百上千万的请求到达我们的接口,即瞬间这股巨大的流量将涌入我们的系统,我们可以采用下面一图来大致体现这一现象:

    enter image description here

    当到了“开始秒杀”、“开始抢单”的时刻,此时系统可能会出现这样的几种现象:

    • 应用系统配置承载不了这股瞬间流量,导致系统直接挂掉,即传说中的“宕机”现象;
    • 接口逻辑没有考虑并发情况,数据库读写锁发生冲突,导致最终处理结果跟理论上的结果数据不一致(如商品存库量只有 100,但是高并发情况下,实际表记录的抢到的用户记录数据量却远远大于 100);
    • 应用占据服务器的资源直接飙高,如 CPU、内存、宽带等瞬间直接飙升,导致同库同表甚至可能同 host 的其他服务或者系统出现卡顿或者挂掉的现象;

    于是乎,我们需要寻找解决方案!对于目前来讲,网上均有诸多比较不错的解决方案,在此我顺便提一下我们的应用系统采用的常用解决方案,包括:

    • 我们会将处理抢单的整体业务逻辑独立、服务化并做集群部署;
    • 我们会将那股巨大的流量拒在系统的上层,即将其转移至 MQ 而不直接涌入我们的接口,从而减少数据库读写锁冲突的发生以及由于接口逻辑的复杂出现线程堵塞而导致应用占据服务器资源飙升;
    • 我们会将抢单业务所在系统的其他同数据源甚至同表的业务拆分独立出去服务化,并基于某种 RPC 协议走 HTTP 通信进行数据交互、服务通信等等;
    • 采用分布式锁解决同一时间同个手机号、同一时间同个 IP 刷单的现象;

    下面,我们用 RabbitMQ 来实战上述的第二点!即我们会在“请求” -> "处理抢单业务的接口" 中间架一层消息中间件做“缓冲”、“缓压”处理,如下图所示:

    enter image description here

    并发量配置与消息确认机制

    正如上面所讲的,对于抢单、秒杀等高并发系统而言,如果我们需要用 RabbitMQ 在 “请求” - “接口” 之间充当限流缓压的角色,那便需要我们对 RabbitMQ 提出更高的要求,即支持高并发的配置,在这里我们需要明确一点,“并发消费者”的配置其实是针对 listener 而言,当配置成功后,我们可以在 MQ 的后端控制台应用看到 consumers 的数量,如下所示:

    enter image description here

    其中,这个 listener 在这里有 10 个 consumer 实例的配置,每个 consumer 可以预监听消费拉取的消息数量为 5 个(如果同一时间处理不完,会将其缓存在 mq 的客户端等待处理!)

    另外,对于某些消息而言,我们有时候需要严格的知道消息是否已经被 consumer 监听消费处理了,即我们有一种消息确认机制来保证我们的消息是否已经真正的被消费处理。在 RabbitMQ 中,消息确认处理机制有三种:Auto - 自动、Manual - 手动、None - 无需确认,而确认机制需要 listener 实现 ChannelAwareMessageListener 接口,并重写其中的确认消费逻辑。在这里我们将用 “手动确认” 的机制来实战用户商城抢单场景。

    1.在 RabbitMQConfig 中配置确认消费机制以及并发量的配置

    enter image description here

    2.消息模型的配置信息

    enter image description here

    3.RabbitMQ 后端控制台应用查看此队列的并发量配置

    enter image description here

    4.listener 确认消费处理逻辑:在这里我们需要开发抢单的业务逻辑,即“只有当该商品的库存 >0 时,抢单成功,扣减库存量,并将该抢单的用户信息记录入表,异步通知用户抢单成功!”

    enter image description here

    enter image description here

    紧接着我们采用 CountDownLatch 模拟产生高并发时的多线程请求(或者采用 jmeter 实施压测也可以!),每个请求将携带产生的随机数:充当手机号 -> 充当消息,最终入抢单队列!在这里,我模拟了 50000 个请求,相当于 50000 手机号同一时间发生抢单的请求,而设置的产品库存量为 100,这在 product 数据库表即可设置

    enter image description here

    6.将抢单请求的手机号信息压入队列,等待排队处理

    enter image description here

    7.在最后我们写个 Junit 或者写个 Controller,进行 initService.generateMultiThread(); 调用模拟产生高并发的抢单请求即可

    @RestController
        public class ConcurrencyController {
    
        private static final Logger log= LoggerFactory.getLogger(HelloWorldController.class);
    
        private static final String Prefix="concurrency";
    
        @Autowired
        private InitService initService;
    
        @RequestMapping(value = Prefix+"/robbing/thread",method = RequestMethod.GET)
        public BaseResponse robbingThread(){
            BaseResponse response=new BaseResponse(StatusCode.Success);
            initService.generateMultiThread();
            return response;
        }}

    8.最后,我们当然是跑起来,在控制台我们可以观察到系统不断的在产生新的请求(线程)– 相当于不断的有抢单的手机号涌入我们的系统,然后入队列,listener 监听到请求之后消费处理抢单逻辑!最后我们可以观察两张数据库表:商品库存表、商品成功抢单的用户记录表 - 只有当库存表中商品对应的库存量为 0、商品成功抢单的用户记录刚好 100 时 即表示我们的实战目的以及效果已经达到了!!

    enter image description here

    总结:如此一来,我们便将 request 转移到我们的 mq,在一定程度缓解了我们的应用以及接口的压力!当然,实际情况下,我们的配置可能远远不只代码层次上的配置,比如我们的 mq 可能会做集群配置、负载均衡、商品库存的更新可能会考虑分库分表、库存更新可能会考虑独立为库存 Dubbo 服务并通过 Rest Api 异步通信交互并独立部署等等。这些优化以及改进的目的其实无非是为了能限流、缓压、保证系统稳定、数据的一致等!而我们的 MQ,在其中可以起到不可磨灭的作用,其字如其名:“消息队列”,而队列具有 “先进先出” 的特点,故而所有进入 MQ 的消息都将 “乖巧” 的在 MQ 上排好队,先来先排队,先来先被处理消费,由此一来至少可以避免 “瞬间时刻一窝蜂的 request 涌入我们的接口” 的情况!

    附注:在用 RabbitMQ 实战上述高并发抢单解决方案,其实我也在数据库层面进行了优化,即在读写存库时采用了“类似乐观锁”的写法,保证:抢单的请求到来时有库存,更新存库时保证有库存可以被更新!

    彩蛋:本博文介绍了几个典型的RabbitMQ实战的业务场景,相关源码数据库可以来这里下载

    (1)https://download.csdn.net/download/u013871100/10654482

    (2)https://pan.baidu.com/s/1KUuz_eeFXOKF3XRMY2Jcew
    学习过程有任何问题均可以与我交流,技术交流群:605610429(Java实战基地交流1群)

    下一篇博文将继续典型应用场景实战之死信队列的应用。感兴趣的童鞋可以关注一下我的微信公众号!

    展开全文
  • 转发和重定向区别详解 作为一名程序员,特别是java web开发的程序员,在使用... 1、RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法不仅可以重定...

    转发和重定向区别详解

            作为一名java web开发的程序员,在使用servlet/jsp的时候,我们必须要知道实现页面跳转的两种方式的区别和联系:即转发和重定向的区别。

          1、request.getRequestDispatcher().forward()方法,只能将请求转发给同一个WEB应用中的组件;而response.sendRedirect() 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。

    如果传递给response.sendRedirect()方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建request.getRequestDispatcher()对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。

          2、重定向访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。

          3、HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。

    由此可见,重定向的时候,“浏览器”一共发出了两封信和收到了两次回复,“浏览器”也知道他借到的钱出自李四之手。

    request.getRequestDispatcher().forward()方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。

    由此可见,转发的时候,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。

           4、request.getRequestDispatcher().forward()方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;

    而response.sendRedirect()方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用request.getRequestDispatcher().forward()方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用response.sendRedirect()方法。

            5、无论是request.getRequestDispatcher().forward()方法,还是response.sendRedirect()方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中。

    以上五点的论述来源于:点击查看原文论述

    转发和重定向的图解

    两种跳转获得对象的方式

    //获得转发对象getRequestDispatcher()
    HttpServletRequest(httpServletRequest).getRequestDispatcher
    ServletContext.getRequestDispatcher();
    
    //获得重定向对象sendRedirect()
    HttpServletResponse(httpServletResponse).sendRedirect();

    转发和跳转的小结

          1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();

          2、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;

          3、转发是服务器行为,重定向是客户端行为;

          4、转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;

          5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

    转发和重定向的选择

          1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。

          2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

    转发和重定向的应用场景

           在上面我已经提到了,转发是要比重定向快,因为重定向需要经过客户端,而转发没有。有时候,采用重定向会更好,若需要重定向到另外一个外部网站,则无法使用转发。另外,重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作。

           例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动作;这在一个真实的应用程序中,很有可能将表单中的所有产品信息加入到数据库中。但是如果在提交表单后,重新加载页面,执行保存的方法就很有可能再次被调用。同样的产品信息就将可能再次被添加,为了避免这种情况,提交表单后,你可以将用户重定向到一个不同的页面,这样的话,这个网页任意重新加载都没有副作用;

           但是,使用重定向不太方便的地方是,使用它无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。由于重定向经过客户端,所以Model中的一切都会在重定向时丢失。但幸运的是,在Spring3.1版本以后,我们可以通过Flash属性,解决重定向时传值丢失的问题。

           要使用Flash属性,必须在Spring MVC的配置文件中添加一个<annotation-driven/>。然后,还必须再方法上添加一个新的参数类型:org.springframework.web.servlet.mvc.support.RedirectAttributes。

           如下所示:

    @RequestMapping(value="saveProduct",method=RequestMethod.POST)
    public String saveProduct(ProductForm productForm,RedirectAttributes redirectAttributes){
    
         //执行产品保存的业务逻辑等
      
         //传递参数
           redirectAttributes.addFlashAttribute("message","The product is saved successfully");
       
         //执行重定向
          return "redirect:/……";
    }

     

     

     

     

    展开全文
  • 区块链七大应用场景

    万次阅读 多人点赞 2019-09-05 18:47:11
    一、应用场景:信息共享 这应该是区块链最简单的应用场景,就是信息互通有无。 1、传统的信息共享的痛点 要么是统一由一个中心进行信息发布和分发,要么是彼此之间定时批量对账(典型的每天一次),对于有时效性...

    一、应用场景:信息共享

    这应该是区块链最简单的应用场景,就是信息互通有无。

    1、传统的信息共享的痛点

    要么是统一由一个中心进行信息发布和分发,要么是彼此之间定时批量对账(典型的每天一次),对于有时效性要求的信息共享,难以达到实时共享。

    信息共享的双方缺少一种相互信任的通信方式,难以确定收到的信息是否是对方发送的。

    2、区块链 + 信息共享

    首先,区块链本身就是需要保持各个节点的数据一致性的,可以说是自带信息共享功能;其次,实时的问题通过区块链的P2P技术可以实现;最后,利用区块链的不可篡改和共识机制,可构建其一条安全可靠的信息共享通道。

    也行你会有这样的疑问:解决上面的问题,不用区块链技术,我自己建个加密通道也可以搞定啊!但我想说,既然区块链技术能够解决这些问题,并且增加节点非常方便,在你没有已经建好一套安全可靠的信息共享系统之前,为什么不用区块链技术呢?

    3、应用案例

    举下我们腾讯自己的应用--公益寻人链,借用如下一张好图,可以看到,区块链在信息共享中发挥的价值。

    浅谈区块链的七大应用场景

    二、应用场景:版权保护

    1、传统鉴证证明的痛点

    流程复杂:以版权保护为例,现有鉴证证明方式,登记时间长,且费用高。

    公信力不足:以法务存证为例,个人或中心化的机构存在篡改数据的可能,公信力难以得到保证。

    2、区块链 + 鉴证证明

    流程简化:区块链应用到鉴证证明后,无论是登记还是查询都非常方便,无需再奔走于各个部门之间。

    安全可靠:区块链的去中心化存储,保证没有一家机构可以任意篡改数据。

    3、应用案例

    区块链在鉴权证明领域的应用有版权保护、法务存证等,下面以版权保护为例,简单说下如何区块链如何实现版权登记和查询。

    (1)电子身份证:将“申请人+发布时间+发布内容”等版权信息加密后上传,版权信息用于唯一区块链ID,相当拥有了一张电子身份证。

    (2)时间戳保护:版权信息存储时,是加上时间戳信息的,如右雷同,可用于证明先后。

    (3)可靠性保证:区块链的去中心化存储、私钥签名、不可篡改的特性提升了鉴权信息的可靠性。

    2016年8月,由Onchain、微软(中国)、法大大等多个机构在北京成立了电子存证区块链联盟“法链”。

    2017年12月,微众银行、仲裁委(广州仲裁委)、杭州亦笔科技有限公司共同推出的仲裁联盟链,用于司法场景下的存证;2018年3月,广州首个“仲裁链”判决书出炉。

    三、应用场景:物流链

    浅谈区块链的七大应用场景

    商品从生产商到消费者手中,需要经历多个环节(流程可能如上图所示),跨境购物则更加复杂;中间环节经常出问题,消费者很容易购买的假货。而假货问题正是困扰着各大商家和平台,至今无解。

    1、传统是防伪溯源手段

    以一直受假冒伪劣产品困扰的茅台酒的防伪技术为例,2000年起,其酒盖里有一个唯一的RFID标签,可通过手机等设备以NFC方式读出,然后通过茅台的APP进行校验,以此防止伪造产品。 咋一看,这种防伪效果非常可靠。但2016年还是引爆了茅台酒防伪造假,虽然通过NFC方式验证OK,但经茅台专业人士鉴定为假酒。后来,在“国酒茅台防伪溯源系统”数据库审计中发现80万条假的防伪标签记录,系防伪技术公司人员参与伪造;随后,茅台改用安全芯片防伪标签。

    但这里暴露出来的痛点并没有解决,即防伪信息掌握在某个中心机构中,有权限的人可以任意修改。(备注:茅台的这种防伪方式,也衍生了旧瓶回收,旧瓶装假酒的产业,防伪道路任重而道远)。

    2017年05月贵阳数博会上,小马哥就建议茅台防伪使用区块链;那么区块链和物流链的结合有什么优势呢?

    2、区块链+物流链

    区块链没有中心化节点,各节点是平等的,掌握单个节点无法实现修改数据;需要掌控足够多的节点,才可能伪造数据,大大提高伪造数据的成本。

    区块链天生的开放、透明,使得任何人都可以公开查询,伪造数据被发现的概率大增。

    区块链的数据不可篡改性,也保证了已销售出去的产品信息已永久记录,无法通过简单复制防伪信息蒙混过关,实现二次销售。

    物流链的所有节点上区块链后,商品从生产商到消费者手里都有迹可循,形成完整链条;商品缺失的环节越多,将暴露出其是伪劣产品概率更大。

    3、应用案例

    目前,入局物流链的玩家较多,包括腾讯、阿里、京东、沃尔玛等。 据说,阿里的菜鸟在海淘进口应用区块链上,走在了前面,已经初步实现海外商品溯源,国际物流及进口申报溯源、境内物流溯源;下一步就是生产企业溯源了。下图是网上流传的关于阿里的菜鸟在海淘场景运用区块链的示意图。

    浅谈区块链的七大应用场景

    另据最新消息,在3月份的第三届全球物流技术大会上,腾讯与中国物流与采购联合会(简称“中物联”)正式签署战略合作协议,并发布了区块链物流平台。强强联合,想象空间很大。

    四、应用场景:供应链金融

    1、传统的供应链单点融资

    在一般供应链贸易中,从原材料的采购、加工、组装到销售的各企业间都涉及到资金的支出和收入,而企业的资金支出和收入是有时间差的,这就形成了资金缺口,多数需要进行融资生产。我们先来看个简单的供应链(复杂的我也不了解(⊙o⊙)),如下图:

    浅谈区块链的七大应用场景

    我们再来看看图中各个角色的融资情况:

    核心企业或大企业:规模大、信用好,议价能力强,通过先拿货后付款,延长账期将资金压力传导给后续供应商;此外,其融资能力也是最强的。

    一级供应商:通过核心企业的债权转让,可以获得银行的融资。

    其他供应商(多数是中小微企业):规模小、发展不稳定、信用低,风险高,难以获得银行的贷款;也无法想核心企业一样有很长的账期;一般越小的企业其账期越短,微小企业还需要现金拿货。这样一出一入对比就像是:中小微企业无息借钱给大企业做生意。

    2、区块链+供应链金融

    面对,上述供应链里的中小微企业融资难问题,主要原因是银行和中小企业之间缺乏一个有效的信任机制。

    假如供应链所有节点上链后,通过区块链的私钥签名技术,保证了核心企业等的数据可靠性;而合同、票据等上链,是对资产的数字化,便于流通,实现了价值传递。

    浅谈区块链的七大应用场景

    如上图所示,在区块链解决了数据可靠性和价值流通后,银行等金融机构面对中小企业的融资,不再是对这个企业进行单独评估;而是站在整个供应链的顶端,通过信任核心企业的付款意愿,对链条上的票据、合同等交易信息进行全方位分析和评估。即借助核心企业的信用实力以及可靠的交易链条,为中小微企业融资背书,实现从单环节融资到全链条融资的跨越,从而缓解中小微企业融资难问题。

    3、应用案例

    比较成熟的还没看到,目前腾讯也已入局。

    五、应用场景:跨境支付

    1、传统跨境支付

    浅谈区块链的七大应用场景

    跨境支付涉及多种币种,存在汇率问题,传统跨境支付非常依赖于第三方机构,大致的简化模型如上图所示,存在着两个问题;

    流程繁琐,结算周期长:传统跨境支付基本都是非实时的,银行日终进行交易的批量处理,通常一笔交易需要24小时以上才能完成;某些银行的跨境支付看起来是实时的,但实际上,是收款银行基于汇款银行的信用做了一定额度的垫付,在日终再进行资金清算和对账,业务处理速度慢。

    手续费高:传统跨境支付模式存在大量人工对账操作,加之依赖第三方机构,导致手续费居高不下,麦肯锡《2016全球支付》报告数据显示,通过代理行模式完成一笔跨境支付的平均成本在25美元到35美元之间。

    2、区块链+跨境支付

    这些问题的存在,很大原因还是信息不对称,没有建立有效的信任机制。

    浅谈区块链的七大应用场景

    如上图所示,区块链的引入,解决了跨境支付信息不对称的问题,并建立起一定程度的信任机制;带来了两个好处。

    效率提高,费用降低:接入区块链技术后,通过公私钥技术,保证数据的可靠性,再通过加密技术和去中心,达到数据不可篡改的目的,最后,通过P2P技术,实现点对点的结算;去除了传统中心转发,提高了效率,降低了成本(也展望了普及跨境小额支付的可能性)。

    可追溯,符合监管需求:传统的点对点结算不能不规模应用,除了信任问题,还有就是存在监管漏洞(点对点私下交易,存在洗黑钱的风险),而区块链的交易透明,信息公开,交易记录永久保存实现了可追溯,符合监管的需求。

    3、应用案例

    应用现状:Ripple、Circle、招商银行等已经入局。

    六、应用场景:资产数字化

    1、实体资产存在的问题

    实体资产往往难以分割,不便于流通

    实体资产的流通难以监控,存在洗黑钱等风险

    2、区块链实现资产数字化

    资产数字化后,易于分割、流通方便,交易成本低

    用区块链技术实现资产数字化后,所有资产交易记录公开、透明、永久存储、可追溯,完全符合监管需求

    3、应用案例

    还是以腾讯的微黄金应用为例,继续借用腾讯区块链官网(trustsql.qq.com)上的图片,可以看到,在资产数字化之后,流通更为方便了,不再依赖于发行机构;且购买0.001g黄金成为了可能,降低了参与门槛。

    浅谈区块链的七大应用场景

    七、应用场景:代币

    本来不像把代币加进来的,但说到区块链,始终绕不开代币;因区块链脱胎于比特币,天生具有代币的属性,目前区块链最成功的应用也正是比特币

    1、传统货币存在的问题

    传统的货币发行权掌握在国家手中,存在着货币滥发的风险

    元朝自1271年建立后,依然四处征战,消耗大量的钱财和粮食,为了财政问题,长期滥发货币,造成严重通货膨胀,多数百姓生活在水生火热中,导致流民四起,国家大乱,1368年,不可一世的元朝成了只有97年短命鬼,走向了灭亡。

    1980年津巴布韦独立,后因土改失败,经济崩溃,政府入不敷出,开始印钞;2001年时100津巴布韦币可兑换约1美元;2009年1月,津央行发行100万亿面值新津元(如下图)加速货币崩溃,最终津元被废弃,改用“美元化”货币政策。2017年津巴布韦发生政变,总统穆加贝被赶下台。

    浅谈区块链的七大应用场景

    传统的记账权掌握在一个中心化的中介机构手中,存在中介系统瘫痪、中介违约、中介欺瞒、甚至是中介耍赖等风险。

    2013年3月,塞浦路斯为获得救助,对银行储户进行一次性征税约58亿欧元, 向不低于10万欧元的存款一次性征税9.9%,向低于10万欧元的一次性征税6.75%。

    2017年4月,民生银行30亿假理财事件暴露,系一支行行长伪造保本保息理财产品所致,超过150名投资者被套。

    2、区块链如何解决这些问题

    浅谈区块链的七大应用场景

    比特币解决了货币在发行和记账环节的信任问题,我们来看下比特币是如何一一破解上面的两个问题。

    滥发问题:比特币的获取只能通过挖矿获得,且比特币总量为2100万个,在发行环节解决了货币滥发的问题; 账本修改问题:比特币的交易记录通过链式存储和去中心化的全球节点构成网络来解决账本修改问题。

    链式存储可以简单理解为:存储记录的块是一块连着一块的,形成一个链条;除第一个块的所有区块都的记录包含了前一区块的校验信息,改变任一区块的信息,都将导致后续区块校验出错。因为这种关联性,中间也无法插入其他块,所以修改已有记录是困难的。

    而去中心化节点可以简单理解为:全球的中心节点都是平等的,都拥有一模一样的账本,所以,任一节点出问题都不影响账本记录。而要修改账本,必须修改超过全球一半的节点才能完成;而这在目前看来几乎不可能。 既然账本无法修改,那要是记账的时候作弊呢? 首先,比特币的每条交易记录是有私钥签名的,别人伪造不了这个记录。你能修改的仅仅自己发起的交易记录。

    其次,是关于记账权问题:比特币的记账权,通过工作量证明获得,可以简单理解为:通过算法确定同一时刻,全球只有一个节点获得了记账权,基本规律是谁拥有的计算资源越多,谁获得记账权的概率越大,只有超过全网一半的算力,才可能实现双花。

    备注:比特币的模式是不可复制的,比特币已经吸引了全球绝大多数的算力,从而降低51%攻击发生等问题;其他的复制品基本无法获得相应的算力保证。

    目前,比特币还存在着51%和效率低等问题有待解决,另外,关于交易本身的信任问题是个社会问题,比特币是没有解决的,也解决不了的。

    3、应用案例

    最具代表性的当然是比特币,也不用多说了。

    备注:代币这块真的不看好,比特币目前吸引了全球绝大部分的算力,有独一无二的算力资源作为支撑还稍好一点,其他的代币和传统的货币相比,其背后缺乏国家和武力为其做信用背书,且夺取了国家发币带来的各种好处(如宏观调控),仔细想想就知道有多不靠谱。

    浅谈区块链的七大应用场景

    结论

    区块链应用的场景肯定还有很多,但很多都还不大明朗,暂时就先梳理以上7种场景,顺便归纳一下。

    浅谈区块链的七大应用场景

    区块链这么火,但实际应用的案例却少之又少;我认为,并非区块链技术目前存在的问题阻碍了其大范围的应用,也不是区块链可以应用的场景非常少,区块链商用牵扯到各方的利益,其最大的难题可能远在技术之外。

    展开全文
  • Redis应用场景1——简单场景

    万次阅读 2014-01-02 22:08:26
    Redis应用场景1——简单场景 Redis应用场景2——广告定向 Redis应用场景3——电商场景 Redis应用场景4——搜索场景 Redis应用场景5——社交网络 1、计数器 redis incrBy就可以了 2、信号量 1)基本信号量...
  • 区块链:典型应用场景

    万次阅读 多人点赞 2019-05-17 18:17:03
    其中很关键的一点便是能否找到合适的应用场景。 以比特币网络为代表的大规模数字货币系统,长时间自治运行,支持了传统金融系统都难以实现的全球范围即时可靠交易。这为区块链技术的应用潜力引发了无限遐想。如果...
  • Redis应用场景3——电商场景

    千次阅读 2019-06-10 00:10:06
    传送门 Redis应用场景1——简单场景 Redis应用场景2——广告定向 Redis应用场景3——电商场景 Redis应用场景4——搜索场景 Redis应用场景5——社交网络 持续更新中。。。 ...
  • Redis应用场景4——搜索场景

    千次阅读 2019-06-10 00:11:00
    传送门 Redis应用场景1——简单场景 Redis应用场景2——广告定向 Redis应用场景3——电商场景 Redis应用场景4——搜索场景 Redis应用场景5——社交网络 持续更新中。。。。 ...
  • 5G十大细分应用场景研究报告

    万次阅读 多人点赞 2019-06-22 17:38:27
    从全球视角来看,目前5G无论是在技术、标准、产业生态还是网络部署等方面都取得了阶段性的成果,5G落地的最后一环——应用场景正逐渐在各行各业实现。5G应用落地有哪些规律?哪些应用最先走向成熟?本报告立足ITU...
  • ZooKeeper典型应用场景

    万次阅读 2017-09-27 17:51:27
    网上对ZK的应用场景也有不少介绍,本文将结合作者身边的项目例子,系统地对ZK的应用场景进行一个分门归类的介绍。 值得注意的是,ZK并非天生就是为这些应用场景设计的,都是后来众多开发者根据其框架的特性
  • 5G 应用及应用场景总结

    千次阅读 2020-04-30 00:56:05
    1.概述 5G技术演进方式与前几代...先要确定应用的需求和场景,包括 “生活”和“社会”两方面内容,然后再去探索发现相对应的具体技术,例如:5G 新空口(New Radio, NR)设计标准就是来源于全新应用场景,其中包括: ...
  • 云端应用典型应用场景

    千次阅读 2016-10-24 16:55:59
    云端应用典型应用场景 Azure能够根据业务变化,快速搭建业务所需的IT系统以支撑相应业务流程 1.提供虚拟机服务,取代购买本地物理服务器 2.快速搭建网站:静态、动态网站,视频网站,社交网站,电子商务网站 3.数据...
  • 5G通信系统应用场景与消费物联网、工业物联网应用场景综合分析 一、5G通信系统应用场景 5G的到来意味着什么?高速率(增强型移动宽带,eMBB)、大容量(大规模机器通信,mMTC)、低时延(高可靠低时延通信,URLLC)是5G...
  • Java集合应用场景

    千次阅读 2019-06-11 14:22:40
    Java集合应用场景
  • RabbitMQ的应用场景以及基本原理介绍

    万次阅读 多人点赞 2017-02-09 23:30:02
    2.应用场景2.1异步处理场景说明:用户注册后,需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 (1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才...
  • lua应用场景

    千次阅读 2018-08-08 22:13:41
    lua应用场景: C和C++编写,性能很好,一般嵌入应用,扩展应用功能和提高性能。 Nginx + lua 处理http请求时,可在11个阶段插入lua脚本 redis + lua 实现原子操作,避免多线程数据不一致的问题 * java ...
  • Spark应用场景

    千次阅读 2019-01-05 18:55:49
    4、Spark应用场景 目前大数据处理场景主要有以下几种类型: 1、复杂的批处理(Batch Data Processing),偏重点在于处理 海量数据的能力,至于处理 速度可忍受,通常的时间可能是在数十分钟到数小时; 2、基于...
  • ActiveMQ应用场景及应用实例总结

    千次阅读 2019-04-05 13:09:03
     本文主要对ActiveMQ应用场景及应用实例进行了总结,本文源码已上传github,链接在文末。
  • kafka的应用场景

    千次阅读 2019-04-11 12:34:58
    关于消息队列的使用 一、消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决...二、消息队列应用场景以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。 ...
  • 机器学习算法应用场景

    万次阅读 2017-09-15 13:25:01
    本文整理了60个机器学习算法应用场景实例,含分类算法应用场景20个、回归算法应用场景20个、聚类算法应用场景10个以及关联规则应用场景10个。包含了天池、DataCastle、DataFountain中所有竞赛场景。 目录 ...
  • RabbitMQ 典型应用场景实战

    千次阅读 2018-09-06 23:30:02
    特别是在一些典型的应用场景以及业务模块中具有重要的作用,比如业务服务模块解耦,异步通信,高并发限流,超时延迟处理等均有广泛的应用! 本场 Chat 我将开始从官网的权威开发手册简要的介绍 RabbitMQ,然后将以 ...
  • Redis典型应用场景

    千次阅读 2019-03-26 23:15:50
    Redis典型应用场景 Redis典型应用场景 (1)缓存系统 【1】表示客户端发请求到App Server(Apache or Nginx代理服务器) 【2】表示App Server请求Redis缓存数据库,如果Redis缓存数据库有值,则直接执行步骤...
  • Redis发布订阅和应用场景

    万次阅读 2017-11-10 08:46:39
    发布订阅-应用场景 Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的...
  • 本课程主要是介绍并实战一款java中间件~redisson,介绍redisson相关的核心技术栈及其典型的应用场景,其中的应用场景就包括布隆过滤器、限流器、短信发送、实时/定时邮件发送、数据字典、分布式服务调度等等,在...
  • Redis应用场景2——广告定向

    千次阅读 2019-06-09 22:36:17
    传送门 Redis应用场景1——简单场景 Redis应用场景2——广告定向 Redis应用场景3——电商场景 Redis应用场景4——搜索场景 Redis应用场景5——社交网络 待续。。。。 ...
  • Spring简介、框架核心、优缺点、应用场景

    万次阅读 多人点赞 2019-10-29 23:34:33
    文章目录Spring简介Spring的设计目标Spring的优缺点优点缺点Spring的应用场景 Spring简介 Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题...
  • hadoop应用场景总结

    万次阅读 多人点赞 2017-01-05 12:33:46
    我个人接触hadoop仅仅不到一年,因为是业余时间学习,故...今天总结一篇关于hadoop应用场景的文章,自认为这是学习hadoop的第一步,本文主要解答这几个问题: hadoop的十大应用场景? hadoop到底能做什么? 2012年美国
  • 动态代理是什么?应用场景

    万次阅读 2019-06-17 10:00:39
    应用场景? 动态代理:在运行时,创建目标类,可以调用和扩展目标类的方法。 Java 中实现动态的方式:JDK 中的动态代理和 Java类库 CGLib。 应用场景如: 统计每个 api 的请求耗时 统一的日志输出 校验被...
  • ArrayList和LinkedList的区别、优缺点以及应用场景

    万次阅读 多人点赞 2018-12-09 09:17:21
    他们都可以对元素的增删改查进行操作,那么他们区别、优缺点应用场景都有哪些呢?我们通过源码和数据结构来说明一下 ArrayList和LinkedList的大致区别如下: ArrayList是实现了基于动态数组的数据结构,LinkedList是...
  • 详解 Redis 应用场景及应用实例

    万次阅读 多人点赞 2016-03-23 21:20:10
    1. MySql+Memcached架构的问题 2. Redis常用数据类型 3. 各种数据类型应用和实现方式 4. Redis实际应用场景

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 162,613
精华内容 65,045
关键字:

应用场景