首页 > 其他分享 >短视频app制作,实现数据隔离可选方案有很多

短视频app制作,实现数据隔离可选方案有很多

时间:2024-04-28 09:24:14浏览次数:23  
标签:视频 return 隔离 数据源 app template key public String

一、JDBC数据源隔离

在这里插入图片描述

在短视频app制作中,数据隔离需要对DB,Redis,RabbitMQ进行数据隔离

通过实现Spring动态数据源AbstractRoutingDataSource,通过ThreadLocal识别出来压测数据,如果是压测数据就路由到影子库,如果是正常流量则路由到主库,通过流量识别的改造,各个服务都已经能够识别出压测的请求流量了。

代码实现

数据源路由Key持有对象

根据路由Key将选择将操作路由给那个数据源

/**
 * 动态数据源上下文
 */
public class DynamicDataSourceContextHolder {
    public static final String PRIMARY_DB = "primary";
    public static final String SHADOW_DB = "shadow";

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>() {
        /**
         * 将 master 数据源的 key作为默认数据源的 key
         */
        @Override
        protected String initialValue() {
            return PRIMARY_DB;
        }
    };


    /**
     * 数据源的 key集合,用于切换时判断数据源是否存在
     */
    public static List<Object> dataSourceKeys = new ArrayList<>();

    /**
     * 切换数据源
     *
     * @param key
     */
    public static void setDataSourceKey(String key) {
        contextHolder.set(key);
    }

    /**
     * 获取数据源
     *
     * @return
     */
    public static String getDataSourceKey() {
        return contextHolder.get();
    }

    /**
     * 重置数据源
     */
    public static void clearDataSourceKey() {
        contextHolder.remove();
    }

    /**
     * 判断是否包含数据源
     *
     * @param key 数据源key
     * @return
     */
    public static boolean containDataSourceKey(String key) {
        return dataSourceKeys.contains(key);
    }

    /**
     * 添加数据源keys
     *
     * @param keys
     * @return
     */
    public static boolean addDataSourceKeys(Collection<? extends Object> keys) {
        return dataSourceKeys.addAll(keys);
    }
}

 

动态数据源实现类

根据路由Key实现数据源的切换

/**
 * 动态数据源实现类
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 如果不希望数据源在启动配置时就加载好,可以定制这个方法,从任何你希望的地方读取并返回数据源
     * 比如从数据库、文件、外部接口等读取数据源信息,并最终返回一个DataSource实现类对象即可
     */
    @Override
    protected DataSource determineTargetDataSource() {
        //获取当前的上下文
        WormholeContext wormholeContext = WormholeContextHolder.getContext();
        //如果不为空使用影子库
        if (null != wormholeContext) {
            DynamicDataSourceContextHolder.setDataSourceKey(DynamicDataSourceContextHolder.SHADOW_DB);
        } else {
            //为空则使用主数据源
            DynamicDataSourceContextHolder.setDataSourceKey(DynamicDataSourceContextHolder.PRIMARY_DB);
        }
        return super.determineTargetDataSource();
    }

    /**
     * 如果希望所有数据源在启动配置时就加载好,这里通过设置数据源Key值来切换数据,定制这个方法
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }

 
}

 

二、Redis 数据源隔离

同时通过ThreadLocal识别出来压测数据,自定义Redis的主键的序列化方式,如果是压测数据则在主键后面加上后缀,这样就可以通过不同主键将Redis数据进行隔离。

实现key序列化

public class KeyStringRedisSerializer extends StringRedisSerializer {

    @Resource
    private WormholeIsolationConfiguration isolationConfiguration;

    public byte[] serialize(@Nullable String redisKey) {
        WormholeContext wormholeContext = WormholeContextHolder.getContext();
        if (null != wormholeContext) {
            redisKey = isolationConfiguration.generateIsolationKey(redisKey);
        }
        return super.serialize(redisKey);
    }
}

 

配置序列化器

/**
 * Redis 配置类
 */
@Configuration
@ConditionalOnClass({RedisTemplate.class, RedisOperations.class, RedisConnectionFactory.class})
public class WormholeRedisAutoConfiguration {


    @Bean
    public KeyStringRedisSerializer keyStringRedisSerializer() {
        return new KeyStringRedisSerializer();
    }

    @Bean("redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate();
        //使用fastjson序列化
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);
        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(keyStringRedisSerializer());
        template.setHashKeySerializer(keyStringRedisSerializer());
        template.setConnectionFactory(factory);
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setKeySerializer(keyStringRedisSerializer());
        template.setHashKeySerializer(keyStringRedisSerializer());
        template.setConnectionFactory(factory);
        return template;
    }
}

 

三、RabbitMQ 数据隔离

在这里插入图片描述

自动创建影子队列

因为SpringAMQP中的
中的关键方法是私有的,无法通过继承的方式进行实现对以配置好的队列进行扩展,所以需要自定义该类,来实现对自动创建影子队列,并和交换器进行绑定
在这里插入图片描述

代码实现

改造RabbitListenerAnnotationBeanPostProcessor类来实现创建MQ影子队列以及将影子Key绑定到影子队列。

public class WormholeRabbitListenerAnnotationBeanPostProcessor extends RabbitListenerAnnotationBeanPostProcessor {

    @Resource
    private WormholeIsolationConfiguration wormholeIsolationConfiguration;

    /**
     * routingKey 前置处理器
     *
     * @param queueName
     * @param routingKey
     * @return
     */
    @Override
    public String preProcessingRoutingKey(String queueName, String routingKey) {
        //如果是影子队列就将routingKey转换为 影子routingKey
        if (wormholeIsolationConfiguration.checkIsolation(queueName) && !wormholeIsolationConfiguration.checkIsolation(routingKey)) {
            return wormholeIsolationConfiguration.generateIsolationKey(routingKey);
        }
        return routingKey;
    }

    /**
     * 处理队列问题,如果来了一个队列就生成一个shadow的队列
     *
     * @param queues
     * @return
     */
    @Override
    public List<String> handelQueues(List<String> queues) {
        List<String> isolationQueues = new ArrayList<>();
        if (null != queues && !queues.isEmpty()) {
            for (String queue : queues) {
                //添加shadow队列
                isolationQueues.add(wormholeIsolationConfiguration.generateIsolationKey(queue));
            }
            queues.addAll(isolationQueues);
        }
        return queues;
    }
}

 

传递染色标识
因为在短视频app制作中MQ是异步通讯,为了传递染色标识,会在发送MQ的时候将染色标识传递过来,MQ接收到之后放进当前线程的ThreadLocal里面,这个需要扩展Spring的SimpleRabbitListenerContainerFactory来实现
在这里插入图片描述

代码实现

public class WormholeSimpleRabbitListenerContainerFactory extends SimpleRabbitListenerContainerFactory {

    @Override
    protected SimpleMessageListenerContainer createContainerInstance() {
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setAfterReceivePostProcessors(message -> {
            //防止线程复用 销毁ThreadLocal
            WormholeContextHolder.invalidContext();
            //获取消息属性标识
            String wormholeRequestContext = message.getMessageProperties().getHeader(WormholeContextHolder.WORMHOLE_REQUEST_MARK);
            if (StringUtils.isNotEmpty(wormholeRequestContext)) {
                WormholeContextHolder.setContext(wormholeRequestContext);
            }
            return message;
        });
        return simpleMessageListenerContainer;
    }
}

 

发送MQ消息处理
同上,需要传递染色标识,就通过继承RabbitTemplate重写convertAndSend方法来实现传递染色标识。

public class ShadowRabbitTemplate extends RabbitTemplate {
    public ShadowRabbitTemplate(ConnectionFactory connectionFactory) {
        super(connectionFactory);
    }

    @Autowired
    private WormholeIsolationConfiguration isolationConfiguration;

    @Override
    public void send(final String exchange, final String routingKey,
                     final Message message, @Nullable final CorrelationData correlationData)
            throws AmqpException {
        WormholeContext wormholeContext = WormholeContextHolder.getContext();
        if (null == wormholeContext) {
            super.send(exchange, routingKey, message, correlationData);
        } else {
            message.getMessageProperties().setHeader(WormholeContextHolder.WORMHOLE_REQUEST_MARK, wormholeContext.toString());
            //生成Rabbit 隔离Key
            String wormholeRoutingKey = isolationConfiguration.generateIsolationKey(routingKey);
            //调用父类进行发送
            super.send(exchange, wormholeRoutingKey, message, correlationData);
        }
    }
}

 

以上就是短视频app制作,实现数据隔离可选方案有很多, 更多内容欢迎关注之后的文章

 

标签:视频,return,隔离,数据源,app,template,key,public,String
From: https://www.cnblogs.com/yunbaomengnan/p/18162988

相关文章

  • 朋友圈怎么插入高清晰视频
    在朋友圈发高清晰视频,你可以遵循以下步骤和技巧:1.**录制或获取高清视频**:首先,确保你有一个高质量的原始视频。你可以使用专业的相机或手机进行录制,或者使用高清的视频素材。2.**使用视频编辑软件**:使用视频编辑软件,如AdobePremiere、FinalCutPro等,对视频进行剪辑和调整。在......
  • 微信发视频确实存在一些限制,需要注意什么
    微信发视频确实存在一些限制,这些限制主要涉及到视频的长度、大小和格式等方面。首先,对于视频的长度,微信朋友圈小视频的用户可以从手机相册中选择或者现场拍摄,但单个视频时长不能超过1分钟。这主要是出于网络传输效率、用户注意力以及防止滥用的考虑。然而,如果想发送超过1分钟的视......
  • 短视频开发app,不会还有人不知道这些排序算法吧
    一、快速排序(QuickSort)快速排序采用分治法。首先从短视频开发app的数列中挑出一个元素作为中间值。依次遍历数据,所有比中间值小的元素放在左边,所有比中间值大的元素放在右边。然后按此方法对左右两个子序列分别进行递归操作,直到所有数据有序。最理想的情况是,每次划分所选择的......
  • 短视频开发,如何用Java实现短信验证码?
    背景Java是一种短视频开发时比较流行的编程语言,验证码是一种常用的网络安全技术。Java发展至今,网上也出现了各种各样的验证码,本人初学Java,下面是我用Java实现短信验证码的总结。截图展示实现代码短视频开发后台接收前台的kgCaptchaToken进行验证,验证成功执行成功......
  • SpringMVC(1)-@RequestMapping的简单使用
    本文核心内容来自于韩顺平老师的课程@RequestMapping注解可以用来指定控制器或者处理器的某个方法的请求url@ControllerpublicclassUserServlet{@RequestMapping("/login")publicStringlogin(){return"login";}}1@RequestMappi......
  • 使用FFmpeg将视频的分辨率从1080p转换为2160p
    1.要使用FFmpeg将视频的分辨率从1080p转换为2160p(也称为4K),可以使用以下命令行代码:ffmpeg-iinput.mp4-s3840x2160-c:vlibx264-presetslow-crf20output.mp4这里的参数解释如下:-iinput.mp4:指定输入文件。-s3840x2160:设置输出视频的分辨率为3840像素宽和2160像素高......
  • EPAI手绘建模APP资源管理和模型编辑器1
    (10) 资源① 打开资源管理页面。图 15 资源列表-模型 图 16 资源列表-图层 图 17 资源列表-相机 图 18 资源列表-灯光② 资源管理页面包括模型列表、图层列表、相机列表、灯光列表;包括颜色选择页面、贴图选择页面、材质选择页面、样式选择页面。③ 模型......
  • uniapp-common.css
    /*by:https://www.cnblogs.com/zzz7/p/15593167.html*/page{height:100%;width:190%;background-color:#F8F8F8;}.container{height:100%;width:100%;}/*主题色*/.main-color{color:#1bbf80;}.white-color{color:#ffffff;......
  • EPAI手绘建模APP模型库
    (9) 库① 打开手绘建模模型集。 图 11 手绘建模模型集② 宫格显示所有创建和保存的模型,每个模型包括模型图片文件、模型文件名称、模型文件大小、修改日期。③ 在收藏的模型的图片左上角用☆标记。④ 点击搜索按钮,进入搜索;输入搜索关键字,显示所有符合条件的模型。......
  • 名表维修保养:uniapp 微信小程序自定义导航栏 详细步骤
    组件使用:  <navbarclass="header":background="backgroundColor"backtitle="标题"@onBack="goBack"></navbar>组件引用:  importnavbarfrom'@/components/NavBer.vue';组件注册:  components:{navbar......