java高并发实战<1>

news2024/10/5 22:22:16

我们一个请求--->tomcat--->db  我们只需要把我们的应用部署在tomcat中,  
就可以了
这就是你单体的感念,单机结构你只用一个服务器就完成了你项目的部署

单点问题一旦这台机器挂了,用户就没有办法用你这个服务,单机能力有限 随着你用户量增长的过程中  用户越来越多,呢你此时的应用你的db就不能承受这么多用户了,所以这个时候要针对于
我们可以做应用和数据进行分离

在这里插入图片描述

这个就是分布式系统,应用和数据分离,用户发起一个请求 tomcat和mysql共同完成我们的响应
整体分布在不同的服务器上来完成我们的用户请求响应的  我们就叫做分布式系统
分布式系统讲的是更多从部署层面,只要你部署超过一台机器 我们就叫做分布式系统
上述系统中还是有些问题的,比如Tomcat存在单点故障问题,一旦Tomcat所在的服务器宕机不可用了,我们就无法提供服务了,所以针对单点故障问题,我们会使用集群来解决,单机处理到达瓶颈的时候,集群中每台服务器就叫做这个集群的一个节点”,所有节点构成了一个集群。每个节点都提供相同的服务,那么这样系统的处理能力就相当于提升了好几倍
当前所有节点的负载情况,决定将这个请求交给哪个节点处理,所以就有了ngixn 做负载
nginx 做负载 有负载均衡算法

在这里插入图片描述

我们一般访问的会是服务的域名的,比如说我们访问京东
我们此时是根据域名进行轮询调用后端的服务  比如说tomcat1 或者tomcat2
我们做集群后 通常要做负载均衡

在这里插入图片描述

将请求交给ngixn,再经过ngixn分发给对应的服务器,我nginx仅仅做到的将请求进行转发

在这里插入图片描述


应用+组件 是我们的系统,
##比如说我们的旅游项目 叫做应用
##它附属的组件 叫做组件

单体应用架构 从部署角度来看
最终打包的过程中 你一个项目全部东西打到一个jar包中


在这里插入图片描述

这就是我们的单体应用
随着我们的项目越来越大 参与的人数越来越多  模块越来越多  沟通能力越来越多
甚至项目部署 我可能会影响到你 的内容 对部署来说也比较困难\


###> 然后我们会将我们的应用进行拆分 拆分为垂直应用架构

在这里插入图片描述

 我将我的项目进行拆分,我就会有3个团队来负责开发 , 这样的拆分相互部署不会有影响
  比如说A服务挂了 不会影响B服务

在这里插入图片描述

##缺点就是说 会有相同的代码重复 比如说
前端系统登录 你要写一个登录  后台系统需要登录 你也要写一个登录 
所以 我们后续会有分布式架构,我们把重复的工作进行抽取

在这里插入图片描述

springcloud
>我们的整体项目部署

在这里插入图片描述

然后我们的秒杀功能

在这里插入图片描述

nginx 进行请求的分发,我们可以实现我们的nginx 高可用
gateway 集群,  canal 做数据同步
mysql优化 可以实现读写分离  分库分表

redis+token 的方式 实现分布式session
>>>>>>>我们把我们的配置统一放在nacos上
我们统一的入口是我们的网关  我先把我们的网关跑起来


首先我们要解决的是我们跨域问题 
我们
前端--------->gateway--------->uaa
前端发送请求到后端只要ip或者端口不一致就会出现跨域问题,我们需要在网关中实现跨域
我们需要在网关中实现跨域#

第二就是真实ip 的问题

服务部署登录信息,当我们一个请求
用户--->nginx--->gateway--->uaa 的时候 我们在uaa中做登录的时候 此时uaa服务
当我们在request.getRemoteIp 中是获取的网关的ip  我们怎么拿到用户的真实ip

在这里插入图片描述

package cn.wolfcode.filters;

import cn.wolfcode.common.constants.CommonConstants;
import cn.wolfcode.redis.CommonRedisKey;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 定义全局过滤器,功能如下:
 * 1.把客户端真实IP通过请求同的方式传递给微服务
 * 2.在请求头中添加FEIGN_REQUEST的请求头,值为0,标记请求不是Feign调用,而是客户端调用
 * 3.刷新Token的有效时间
 */
@Component
public class CommonFilter implements GlobalFilter {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * pre拦截逻辑
         * 在请求去到微服务之前,做了两个处理
         * 1.把客户端真实IP通过请求同的方式传递给微服务
         * 2.在请求头中添加FEIGN_REQUEST的请求头,值为0,标记请求不是Feign调用,而是客户端调用
         */
        ServerHttpRequest request = exchange.getRequest().mutate().
                /*在过滤器中拿到ip*/
                header(CommonConstants.REAL_IP,exchange.getRequest().getRemoteAddress().getHostString()).
                header(CommonConstants.FEIGN_REQUEST_KEY,CommonConstants.FEIGN_REQUEST_FALSE).
                build();
        return chain.filter(exchange.mutate().request(request).build()).then(Mono.fromRunnable(()->{
            /**
             * post拦截逻辑
             * 在请求执行完微服务之后,需要刷新token在redis的时间
             * 判断token不为空 && Redis还存在这个token对于的key,这时候需要延长Redis中对应key的有效时间.
             * 没有带token 不会走这里
             */
            String token,redisKey;
            if(!StringUtils.isEmpty(token =exchange.getRequest().getHeaders().getFirst(CommonConstants.TOKEN_NAME))
                    && redisTemplate.hasKey(CommonRedisKey.USER_TOKEN.getRealKey(token))){
                // 我给key 许时间  每次续30分钟
                String s  = CommonRedisKey.USER_TOKEN.getRealKey(token);
                redisTemplate.expire(s  , CommonRedisKey.USER_TOKEN.getExpireTime(), CommonRedisKey.USER_TOKEN.getUnit());
            }
        }));
    }
}

在这里插入图片描述

我们需要在gateway中拿到请求ip放入header中给传递到后续的微服务中
header(CommonConstants.REAL_IP,exchange.getRequest().getRemoteAddress().getHostString())
##>>>

在这里插入图片描述

我们这样就会在uaa中拿到用户的真实ip,
在网关中加个拦截器 fiter 获取到真实的ip地址,转发请求的时候把你的真实ip地址放到请求头中,
在网关中获取用户的真实ip 放在header中传递给下来的微服务中


在这里插入图片描述

LoginLog loginLog = new LoginLog(phone, ip, new Date());
我们要把用户的登录信息记录下来,发送mq进行记录 进行写日志  高频日志记录
我们会专门有一个服务来写日志的,
如果我们的业务数据库除了写业务之后还得插入日志.
业务日志插入比较频繁  势必会影响db的写的性能
所以我们会把数据库进行拆分, 业务和日志db 来分开  mq慢慢写

##   我们此时还得将用户的账号密码信息和用户的基本信息分开

t_user_login 用户账号密码
t_user_base_info  用户基本信息

前端会把token进行缓存  我们用LocalStorage()进行存储token

在这里插入图片描述

  UserLogin userLogin = this.getUser(phone);
###>>>>>>.
userhash  18080018188  userInfo
		  		  17070017177  userInfo 
		  
userZset  17070017177  记录当前key   的时间


我会启动一个定时任务来进行批次得  就是说我要删除7天以外得用户登录,所以用户每次登录进来 我都要刷新时间



private UserLogin getUser(Long phone) {
    UserLogin userLogin;
    String hashKey = "userHash";
    String zSetKey ="userZset";
    String userKey  = String.valueOf(phone);

    String objStr = (String) redisTemplate.opsForHash().get(hashKey, String.valueOf(phone));
    if ("null".equals(objStr) || StringUtils.isEmpty(objStr)) {
        //缓存中并没有,从数据库中查询
        userLogin = userMapper.selectUserLoginByPhone(phone);
        //把用户的登录信息存储到Hash结构中.
        redisTemplate.opsForHash().put(hashKey, userKey, JSON.toJSONString(userLogin));
        //使用zSet结构,value存用户手机号码,分数为登录时间,在定时器中找出7天前登录的用户,然后再缓存中删除.
        //我们缓存中的只存储7天的用户登录信息(热点用户)
    } else {
        //缓存中有这个key
        userLogin = JSON.parseObject(objStr, UserLogin.class);
    }
    //
    redisTemplate.opsForZSet().add(zSetKey, userKey, new Date().getTime());
    return userLogin;
}
token 用户登录成功我会生成一个token 默认为30分钟,

private String createToken(UserInfo userInfo) {
   //token创建
   String token = UUID.randomUUID().toString().replace("-", "");
   //把user对象存储到redis中
   CommonRedisKey redisKey = CommonRedisKey.USER_TOKEN;
   redisTemplate.opsForValue().set(redisKey.getRealKey(token), JSON.toJSONString(userInfo), redisKey.getExpireTime(), redisKey.getUnit());
   return token;
}
##############>>>>>>>>  然后在用户每次请求后 我都会给这个用户来续时间
你每次访问的时候我们都要延迟一下有效时间  >>>>>>>..
每次访问的时候 我要对token进行刷新
后置拦截 意思是我要让我每个接口都给toknen 续命  一定是我不用这个软件的后续30分钟
保证我们的token 始终是有效的  当你没有活跃后的30分钟后失效de
##>>>>登录得缓存设计

在这里插入图片描述


限时抢购场景
首页秒杀列表功能 场次的秒杀 场次----->秒杀场次对应的商品

在这里插入图片描述

首先第一步  商家要在后台上架秒杀商品,
##>我此时我要查询秒杀商品,我就得做rpc发起调用
商品服务      t_ptoduct
秒杀服务      t_seckil_product
做rpc  我们进行微服务拆分后很多都是单表查询

在这里插入图片描述

rpc远程调用我们用到了feign 
##>秒杀服务--------->商品服务  我们此时会用到feign降级, 如果服务挂了或者说超时了


在这里插入图片描述

按照我们的请求 是查询到了 基于场次找到对应的秒杀商品信息

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

04.添加自定义监控项

添加自定义监控项 监控项就是监控每一个指标 1.命令行&#xff0c;手动取值 [rootyunlong66 ~]# iostat |awk $1 ~/sda/ sda 5.89 36.10 122.71 557910 1896585 [rootyunlong66 ~]# iostat |awk $1 ~/sda/{print $2} 5.892.修改zabbix-age…

OpenNJet下载安装及入门实战教程

一、什么是OpenNJet OpenNJet是一款开放原子开源基金会孵化及运营的开源项目。OpenNJet采用C语言实现。是一款高性能、轻量级的WEB应用及代理软件。    OpenNJet 应用引擎是高性能、轻量级的WEB应用与代理软件。作为云原生服务网格的数据平面&#xff0c;NJet具备动态配置加载…

【Git】回滚旧提交版本且不影响最新提交版本

【Git】回滚旧提交版本且不影响最新提交版本 一、场景假设 远程仓库origin中有一个分支main&#xff0c;有4次提交记录&#xff1a;v1、v2、v3、v4。 二、需求 需要回滚旧提交版本&#xff0c;但不影响已有的所有提交版本&#xff08;即不影响最新提交版本&#xff09;&…

k8s保持pod健康

存活探针 Kubemetes 可以通过存活探针 (liveness probe) 检查容器是否还在运行。可以为 pod 中的每个容器单独指定存活探针。如果探测失败&#xff0c;Kubemetes 将定期执行探针并重新启动容器。 Kubemetes 有以下三种探测容器的机制&#xff1a; HTTP GET 探针对容器的 IP 地…

深入探索归并排序算法:分而治之的排序艺术

在计算机科学领域&#xff0c;排序算法是一项基础且重要的技术&#xff0c;归并排序作为一种经典的分治算法&#xff0c;以其稳定性和高效性而闻名。本文将带您深入探索归并排序算法的原理、实现方法以及应用场景&#xff0c;揭示这一排序艺术背后的精髓。 **归并排序算法简介…

【管理篇】管理三步曲:管理规划(一)

目录标题 管理到底都要做哪些事呢如何开始带团队&#xff1f; 职能&#xff1a;如何界定团队是干什么的&#xff1f;目标&#xff1a;如何为团队设定合理的目标规划资源&#xff1a;需要申请哪些资源&#xff08;1&#xff09;你是否了解资源的丰富性&#xff1f;&#xff08;2…

判断dll/lib是32/64位、查看lib是导入库/静态库的方法 、查看dll包含的符合、lib包含的函数

一、判断dll/lib是32/64位 原文链接&#xff1a;https://www.cnblogs.com/bandaoyu/p/16752602.html 1. 简便方法&#xff1a; 直接用记事本或者notepad(或txt文本)打开exe文件&#xff08;dll文件&#xff09;&#xff0c;会有很多乱码&#xff0c;不要头疼&#xff0c;接下…

优雅处理返回信息状态码:Result对象在Spring Boot中的应用

前言 在开发过程中&#xff0c;处理返回的信息状态码是一个重要的问题&#xff0c;尤其是在大型项目中。为了统一处理这些状态码&#xff0c;我在Spring Boot中创建了一个名为Result的Java对象&#xff0c;用于封装返回的信息和状态码。在本文中&#xff0c;我将分享如何实现这…

网络安全的重要性及人才需求

安全现在是大趋势&#xff0c;说是铁饭碗也不为过&#xff0c;就业前景好&#xff0c;方向多比传统计算机行业就业舒服点。但是大厂依然是985&#xff0c;211的天下&#xff0c;是双非能进大厂的&#xff0c;只是凤毛麟角。前提是你的能力可以让公司忽略你的学历。 以2023年为…

Leetcode—622. 设计循环队列【中等】

2024每日刷题&#xff08;128&#xff09; Leetcode—622. 设计循环队列 实现代码 class MyCircularQueue { public:MyCircularQueue(int k): q(k) {qSize k;}bool enQueue(int value) {if(isFull()) {return false;}q[rear] value;rear (rear 1) % qSize;deflag false;…

精准读取CSV/Excel数据 - 灵活指定行列范围的 Python 解决方案

文章目录 源代码项目简介导入相关库__file_exists 装饰器函数的签名和注释主要功能的实现运行演示读取 Excel 文件 源代码 https://github.com/ma0513207162/PyPrecip。pyprecip\reading\read_api.py 路径下。 项目简介 PyPrecip 是一个专注于气候数据处理的 Python 库&#xf…

【STM32嵌入式系统设计与开发】——18DAC(DAC输出应用)

这里写目录标题 STM32资料包&#xff1a; 百度网盘下载链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码&#xff1a;8888 一、任务描述二、任务实施1、工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#…

Python3中Richdem包遇到问题

Python3中Richdem包遇到问题 文章目录 Python3中Richdem包遇到问题问题一报错解决 问题二报错解决 参考 问题一 报错 RichDEM 是一套数字高程模型 &#xff08;DEM&#xff09; 水文分析工具&#xff0c;这次打算用richdem进行地形分析&#xff0c;尝试在conda里面安装richde…

UDP如何端口映射?

UDP端口映射是一种网络技术&#xff0c;通过它可以实现在异地组网的情况下&#xff0c;不暴露在公网上&#xff0c;通过私有通道传输数据&#xff0c;并对数据进行安全加密&#xff0c;以保障数据的安全性。这项技术在如今日益复杂和危险的网络环境中显得尤为重要。 UDP&#x…

【1】STM32·FreeRTOS·新建工程模板【一步到位】

目录 一、获取FreeRTOS源码 二、FreeRTOS源码简介 2.1、FreeRTOS源码文件内容 2.2、FreeRTOS内核 2.3、Source文件夹 2.4、portable文件夹 三、FreeRTOS手把手移植 3.1、FreeRTOS移植准备 3.2、FreeRTOS移植步骤 3.2.1、将 FreeRTOS 源码添加至基础工程、头文件路径等…

构建第一个ArkTS应用之@LocalStorage:页面级UI状态存储

LocalStorage是页面级的UI状态存储&#xff0c;通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内&#xff0c;在页面间共享状态。 本文仅介绍LocalStorage使用场景和相关的装饰器&#xff1a;LocalStorageProp和LocalS…

「 网络安全常用术语解读 」漏洞利用预测评分系统EPSS详解

1. 概览 EPSS&#xff08;Exploit Prediction Scoring System&#xff0c;漏洞利用预测评分系统&#xff09; 提供了一种全新的高效、数据驱动的漏洞管理功能。EPSS是一项数据驱动的工作&#xff0c;使用来自 CVE 的当前威胁信息和现实世界的漏洞数据。 EPSS 模型产生 0 到 1&…

libcity笔记:添加新模型(以RNN.py为例)

创建的新模型应该继承AbstractModel或AbstractTrafficStateModel 交通状态预测任务——>继承 AbstractTrafficStateModel类轨迹位置预测任务——>继承AbstractModel类 1 AbstractTrafficStateModel 2 RNN 2.1 构造函数 2.2 predict 2.3 calculate_loss

【分布式 | 第五篇】何为分布式?分布式锁?和微服务关系?

文章目录 5.何为分布式&#xff1f;分布式锁&#xff1f;和微服务关系&#xff1f;5.1何为分布式&#xff1f;5.1.1定义5.1.2例子5.1.3优缺点&#xff08;1&#xff09;优点&#xff08;2&#xff09;缺点 5.2何为分布式锁&#xff1f;5.2.1定义5.2.2必要性 5.3区分分布式和微服…

ISIS的基本概念

1.ISIS概述 IS-IS是一种链路状态路由协议&#xff0c;IS-IS与OSPF在许多方面非常相似&#xff0c; 例如运行IS-IS协议的直连设备之间通过发送Hello报文发现彼此&#xff0c;然后建立邻接关系&#xff0c;并交互链路状态信息。 CLNS由以下三个部分组成&#xff1a; CLNP&#xf…