分布式解决方案与实战

分布式多线程性能调优

使用多线程优化接口

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

	//下单业务
    public Object order( long userId){
        long start = System.currentTimeMillis();//方法的开始时间戳(ms)

        JSONObject orderInfo = remoteService.createOrder(userId);

        Callable<JSONObject> callable1 = new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                JSONObject goodsInfo = remoteService.dealGoods(orderInfo);
                return goodsInfo;
            }
        };
        Callable<JSONObject> callable2 = new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                JSONObject pointsInfo = remoteService.dealPoints(orderInfo);
                return pointsInfo;
            }
        };
        Callable<JSONObject> callable3 = new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {

                JSONObject deliverInfo = remoteService.dealDeliver(orderInfo);
                return deliverInfo;
            }
        };
        LeeFutureTask<JSONObject> task1 = new LeeFutureTask(callable1);
        LeeFutureTask<JSONObject> task2 = new LeeFutureTask(callable2);
        LeeFutureTask<JSONObject> task3 = new LeeFutureTask(callable3);

        Thread thread1 =new Thread(task1);
        Thread thread2 =new Thread(task2);
        Thread thread3 =new Thread(task3);

        thread1.start();
        thread2.start();
        thread3.start();

        try {
            orderInfo.putAll(task1.get());
            orderInfo.putAll(task2.get());
            orderInfo.putAll(task3.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        long end = System.currentTimeMillis();//方法的开始时间戳(ms)
        System.out.println(end-start);//打印这个方法的执行时间
        return orderInfo;
    }

后台批处理的优化

在这里插入图片描述

public JSONObject orderFastbatch (long userId) throws Exception{

        JSONObject orderInfo = remoteService.createOrderFast(userId);

        //JSONObject goodsInfo = remoteService.dealGoodsFast(orderInfo); //这里是单个的请求,想做成批量+异步的方式
        //orderInfo.putAll(goodsInfo);
        CompletableFuture<JSONObject> future = new CompletableFuture<>();
        Request request = new Request();
        request.future =future;
        request.object = orderInfo;
        queue.add(request);
        return future.get(); //这里类似于FutureTask  的get方法,去异步的方式拿结果
    }

    //定义一个JUC中的MQ
    LinkedBlockingQueue<Request> queue = new LinkedBlockingQueue();
    class Request{
        JSONObject object;
        CompletableFuture<JSONObject> future;
    }

    @PostConstruct
    public void DoBiz(){
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                int size =queue.size();
                if(size ==0) return;//没有数据在queue中,定时任务不需要执行什么

                if(size >1000) size=1000;//这里限制每次批量封装的最多是1000

                List<JSONObject> ListJSONRepuest = new ArrayList<>();
                List<Request>  ListRequest = new ArrayList<>();
                for( int i =0 ;i <size;i++){
                    Request request =queue.poll();//从MQ中拉取
                    ListRequest.add(request);
                    ListJSONRepuest.add(request.object);
                }
                //调用了多少次批量接口
                List<JSONObject> ListJSONReponse  = remoteService.dealGoodsFastBatch(ListJSONRepuest);
                System.out.println("调用批量接口,本地组装的数据:"+size+"条");
                for(JSONObject  JSONReponse:ListJSONReponse){//这里可以使用hashmap 的方式减少一轮遍历。
                    for(Request  request:ListRequest){
                        String  request_OrderId =request.object.get("orderId").toString();
                        String  response_OrderId =JSONReponse.get("orderId").toString();
                       if(request_OrderId.equals(response_OrderId)){
                           request.future.complete(JSONReponse);
                       }
                    }
                }
            }
        }, 3000, 50, TimeUnit.MILLISECONDS);

    }
//处理库存信息 (批量接口)  1000,
    public List<JSONObject> dealGoodsFastBatch( List<JSONObject> objectList) {
        List<JSONObject> list = objectList;
        Iterator it = list.iterator();
        while(it.hasNext()){
            JSONObject result =(JSONObject)it.next();
            result.put("dealGoods", "ok");
        }
        return  list;
    }

批处理与MySQL的综合性优化

如果做了批量处理的话。
1W个请求,高并发请求,其实里面针对的修改库存会集中在一些热点数据8000个在一个商品。
应用层基于批量的接口进行优化。
伪代码:
for循环遍历list,把所有相同的goods_id放到hashmap进行扣减计数即可。

分布式锁

单机锁:sync、lock
MySQL去实现分布式锁–for update (行锁)

Redis

分布式锁的第一种常见方案:Redis来实现分布式锁。Redis key-value键值对的数据库–内存。

Redis的分布式锁的实现逻辑:
1、加锁,setnx key value
1)为了避免死锁问题setnx完之后设置TTL失效时间
2)为了TTL的失效的时候业务还未完成导致的多个应用抢到锁的BUG,这里可以使用一个守护线程,来不断的去续锁(延长key的TTL)

2、解锁del key
无论是加锁,还是解锁,这里涉及到多个命令。要解决原子性问题:
1、复合命令实现加锁。set lock 9527 ex 10 nx
2、解锁的逻辑中:在del之前一定要判断:只有持有锁的应用或线程,才能去解锁成功,否则都是失败。value做文章。存一个唯一标识。

if (get ==应用的保存的值)del
else释放锁失败

使用Lua脚本

锁的可重入。A抢到了锁,没有释放锁之前,依然可以lock进入加锁逻辑的。

Zookeeper

在这里插入图片描述
1、连接ZK、创建分布式锁的根节点/lock
2、一个线程获取锁时,create ()在/lock西面创建1个临时顺序节点3、使用getChildren()获取当前所有字节点,并且对子节点进行排序
4、判断当前创建的节点是否是所有子节点中最小的节点,如果是,则获取锁->执行对应的业务逻辑->在结束的时候使用delete()方法删除该节点。
否则需要等待其他的节点的释放锁、
5、当一个线程需要释放锁的,删除该节点,其他的线程获取当前节点前的一个节点来获取锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IntelliJ IDEA2023学习教程

详细介绍idea开发工具及使用技巧 1. 2023版安装1.1删除老版本1.2 下载及安装 3.快捷技巧4. 创建各种model 1. 2023版安装 1.1删除老版本 如果以前装有idea需要先删除&#xff0c;以避免冲突&#xff0c;在idea安装目录/bin/Uninstall.exe双击1.2 下载及安装 最新版本 https:/…

SpringIOC之FilterType

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

实现进程间的通信

本例程是开发一款能实现进程通信的DLL。本例程以Visual Studio 2015为例。在Visual Studio 2013&#xff0c;Visual Studio 2017都是可以。 第一步&#xff1a;在Visual Studio 2015中&#xff0c;创建DLL工程。如何创建DL&#xff0c;在这里就不作具体说明了。百度都有许多创建…

【Python】—— 文本分析

文本分析 相关知识1. 文本数据处理2. 文本可视化3. Python编程4. 词频统计5. 人名提取6. 自然段划分7. 人物出现频率分布分析8. 词云生成 实验内容数据下载地址&#xff1a;1.对纯英文小说进行分析。2.对中文小说进行分析。 问题与解决附录1.对纯英文小说进行分析。2.对中文小说…

正则化实战( Lasso 套索回归,Ridge 岭回归)

Lasso 套索回归 导入包 import numpy as np from sklearn.linear_model import Lasso from sklearn.linear_model import SGDRegressor, LinearRegression原方程的计算结果 # 1. 创建数据集X&#xff0c;y X 2 * np.random.rand(100, 20) w np.random.rand(20, 1) b np.r…

PyGame字体详解

文章目录 字体初始化获取字体字体对象内置方法 字体初始化 在pygame程序中&#xff0c;第一步势必进行初始化&#xff0c;即调用pygame.init()函数&#xff0c;而此初始化过程&#xff0c;则顺便包含了字体初始化&#xff0c;即默不作声地调用了pygame.font.init()函数。下面通…

FreeModbus--学习函数指针

目录 函数指针 最简单的例子 稍作修改例子 引入协议栈的函数指针 引入协议栈第二处函数指针 函数指针 该协议栈中使用到函数指针&#xff0c;现开展一篇专门存放函数指针的文章。 C语言的函数指针是指向函数的指针变量&#xff0c;可以用来存储和调用函数的地址。在C语言中…

【亲测】获取百度智能云access_token并存储,百度智能云access_token有效期

百度智能云服务内置很多api接口&#xff08;文字识别&#xff0c;企业信息识别&#xff0c;等&#xff09;&#xff0c;所有百度智能云自带的接口都会用到百度的access_token 第一步&#xff1a;登录百度智能云管理中心 第二步&#xff1a;创建账户&#xff0c;完整身份认证 …

智能优化算法应用:基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于乌燕鸥算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.乌燕鸥算法4.实验参数设定5.算法结果6.参考文…

jmeter判断’响应断言‘两个变量对象是否相等

1、首先需要设置变量&#xff0c;json、正则、csv文件等变量 2、然后在响应断言中 ①JMeter Variable Name to use —— 输入一个变量&#xff0c;变量名即可 ② 模式匹配规则 ——相等 ③测试模式 ——输入引用的变量命${变量名} &#xff08;注意这里是需要添加一个测试模式…

安卓开发显示加载中

private ProgressDialog loadobj; // 显示 ProgressDialog loadobj loadobj.show(MainActivity.this, "正在加载", "请稍后..."); // 取消 ProgressDialog loadobj.dismiss();或者 public ProgressDialog progressDialog;public void loading(){// …

流场寻路(Flow Field Path Finding)

简介 当场景中有成千上万个寻路游戏单位需要到达同一目标点时&#xff0c;通过常用的A*算法进行寻路不再是合适的选择&#xff0c;因为每个寻路游戏单位都需要依据自身所在的位置&#xff0c;根据算法获得一条从自身位置寻路到目标点的路径&#xff0c;n个游戏单位进行寻路就需…

人工智能在大型复杂机械产品装配状态检测自动化中的应用

尊敬的读者们&#xff0c;本文主要围绕“大型复杂机械产品装配状态检测自动化方案”开展讨论&#xff0c;从这个领域存在的问题和难度&#xff0c;以及基于人工智能、数字图像处理、机器人控制、装配机理等技术的自动化设计与实践方案。文章提出了数字化建模和智能识别模型构建…

[Springboot 源码系列] 浅析自动配置原理

文章目录 自动配置类原理AopAutoConfigurartion条件装配的底层原理ConditionalConditionalOnXxx 自动配置类原理 public class AutoConfApplication {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.re…

Git命令之本地分支与远程分支支关联/解除关联

目录 1.应用场景2.关联远程仓库中存在的分支3.解除本地分支与远程分支的关联 1.应用场景 在实际的工作生活中&#xff0c;往往需要将本地的分支和远程分支关联&#xff0c;这样我们就可以使用git pull命令来更新拉取最新的代码&#xff0c;并使用git push命令将自己本地的修改…

设备远程监控系统:实时对工厂设备状态进行监控

随着工业4.0时代的到来&#xff0c;工业物联网平台在工业领域的应用越来越广泛。设备远程监控系统作为工业物联网的重要组成部分&#xff0c;能够实时对工厂设备状态进行监控&#xff0c;提高生产效率和管理水平。本文将详细介绍工厂设备数据的采集方式以及设备远程监控系统的应…

企业寄件运费贵?企业如何将企业快递费用降至最低?

按照上述情况&#xff0c;如果使用闪侠惠递商家寄件服务&#xff0c;相较于原本的费用&#xff0c;会节省很大一部分的成本费用的&#xff0c;显而易见&#xff0c;这是非常便宜的。 闪侠惠递的寄件服务支持圆通、德邦、京东、顺丰等多家主流快递公司&#xff0c;并可以对比多…

Git-瑞吉外卖

什么是GIt? 分布式版本控制工具&#xff0c;用来管理源代码文件。分布式主要体现在两种仓库&#xff08;本地仓库、远程仓库&#xff09;。 git的作用&#xff1f; 代码回溯、版本切换&#xff08;切换不同框架&#xff09;、多人协作、远程备份 基本命令&…

虚拟化逻辑架构:KVM虚拟机通过OVS端口组实现网络连接

目录 一、实验 1.CentOS 7 安装 OpenVSwitch(构建RPM安装包&#xff09; 2.KVM虚拟机通过OVS端口组实现网络连接 二、问题 1.安装openvswitch-2.5.10报错 2.virt-install未找到命令 3.如何删除自定义网络 4.开机如何自动启动自定义网络 一、实验 1.CentOS 7 安装 Open…

双指针算法(一)

目录 移动零 复写零 快乐数 盛水最多的容器 双指针与单调性结合 有效三角形的个数 查找总价格为目标值的两个商品 两数之和 Ⅱ - 输入有序数组 双指针算法是通过定义两个指针不断单向移动来解决问题的一种算法。但双指针算法&#xff0c;是一个抽象的思想概念&#xf…