.NET JWT入坑

前言

JWT (JSON Web Token) 是一种安全传输信息的开放标准,由Header、Payload和Signature三部分组成。它主要用于身份验证、信息交换和授权。JWT可验证用户身份,确保访问权限,实现单点登录,并在客户端和服务器之间安全地交换信息。因其简单、安全和便捷,JWT在现代Web应用中广泛使用。

用JWT有多个原因:

  1. 无状态的身份验证:JWT允许服务器无需保存用户的会话信息,因为所有必要的信息都存储在令牌本身中。这降低了服务器的存储需求,并提高了系统的可扩展性。

  2. 跨域身份验证:由于JWT是自我包含的,并且可以被轻松传递,因此它非常适合跨域身份验证。用户可以在一个服务上验证身份,然后使用相同的令牌访问另一个服务,从而实现单点登录(SSO)。

  3. 安全性:JWT可以通过使用强大的加密算法(如HS256, RS256等)进行签名,以确保其完整性和真实性。服务器可以使用公钥验证令牌的签名,从而确保它没有被篡改,并且确实是由受信任的颁发者签发的。

  4. 减少数据库查询:由于用户的身份信息都存储在JWT中,服务器无需每次都去数据库中查询用户的身份信息,从而减少了数据库的压力和查询时间。

  5. 可定制性:JWT的Payload部分可以包含自定义的信息,如用户角色、权限等,这使得JWT非常灵活,并可以根据具体需求进行定制。

  6. 易于分发和共享:JWT可以轻松地通过网络传输,并且可以在多个服务和客户端之间共享,这使得它在微服务架构和分布式系统中非常有用。

  7. 标准化和互操作性:JWT是一个开放标准(RFC 7519),这意味着不同的系统和语言都可以使用相同的方式生成和验证JWT,从而提高了系统的互操作性。

环境 Win10  VS2022  .NET8 

✨ 建立项目jwttest

1.创建TestJwtController

2.下载JWT 

3.建实体类

/// <summary>
/// 用户信息类
/// </summary>
public class LoginRs
{
    /// <summary>
    /// 用户ID
    /// </summary>
    public string UserId { get; set; }
   /// <summary>
   /// 用户密码
   /// </summary>
    public string PasswordMD5 { get; set; }
}
/// <summary>
/// 用户登录信息类
/// </summary>
public class LoginInfo
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public string UserId { get; set; }
    /// <summary>
    /// 检验时间
    /// </summary>
    public DateTime Expires { get; set; }
}
/// <summary>
/// rsmodel
/// </summary>
public class RsModel
{
    /// <summary>
    /// 是否成功
    /// </summary>
    public bool isOk { get; set; }
    /// <summary>
    /// 返回值
    /// </summary>
    public int code { get; set; }
    /// <summary>
    /// 返回消息
    /// </summary>
    public string msg { get; set; }
    /// <summary>
    /// 返回数据  
    /// </summary>
    public object rsData { get; set; }


}

4.添加post login

      // POST api/<ValuesController>
      [HttpPost]
      public string Login([FromBody] LoginRs loginRequest)
      {
          if (loginRequest == null) return JsonConvert.SerializeObject(new RsModel() { code = 0, isOk = false, msg = "登录信息为空!" });

          #region  判断userid pwd

          if (loginRequest.UserId != "admin" || loginRequest.PasswordMD5 != "admin")
          {
              return JsonConvert.SerializeObject(new RsModel() { code = 0, isOk = false, msg = "用户名和密码不正确!" });
          }
          #endregion
          LoginInfo Info = new LoginInfo()
          {
              UserId = loginRequest.UserId,
              Expires = DateTime.Now.AddDays(1)
          };
          const string secretKey = "myseckey";//口令加密秘钥
          byte[] key = Encoding.UTF8.GetBytes(secretKey);
          IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
          IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
          IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
          IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
          var token = encoder.Encode(Info, key);//生成令牌

          return JsonConvert.SerializeObject(new RsModel() { code = 1, isOk = true, rsData = token, msg = "登录成功!" });
      }

5.登录验证

这里使用swagger方便检验    👉    .NET MVC API Swagger入坑

6.测试没问题,写个JwtHelper

 public static class JwtHelper
 {

     private static readonly string JwtKey = "mysecret";
     /// <summary>
     /// 获取加密解密
     /// </summary>
     /// <returns></returns>
     private static IJwtEncoder GetEncoder()
     {
         IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
         IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
         IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
         IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
         return encoder;
     }

     /// <summary>
     /// 获取解密密钥
     /// </summary>
     /// <returns></returns>
     private static IJwtDecoder GetDecoder()
     {
         IJsonSerializer serializer = new JsonNetSerializer();
         IDateTimeProvider provider = new UtcDateTimeProvider();
         IJwtValidator validator = new JwtValidator(serializer, provider);
         IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
         IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
         IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
         return decoder;
     }

     /// <summary>
     /// 加密
     /// </summary>
     public static string Encode(object payload)
     {
         var encoder = GetEncoder();
         var token = encoder.Encode(payload, JwtKey);
         return token;
     }

     /// <summary>
     /// 解密
     /// </summary>
     public static T Decode<T>(string token)
     {
         var decoder = GetDecoder();
         var data = decoder.Decode(token, JwtKey);
         var res = JsonConvert.DeserializeObject<T>(data);
         return res;
     }

     /// <summary>
     /// 解密,只返回Json文本
     /// </summary>
     /// <param name="token"></param>
     /// <returns></returns>
     public static string Decode(string token)
     {

         var decoder = GetDecoder();
         var data = decoder.Decode(token, JwtKey);
         return data;
     }

 }

把中间的加密算法替换成helper的Encode

   var token = JwtHelper.Encode(Info);

7.添加token加密类

调用Decode方法 解密token

8.测试JWT

{"isOk":true,"code":1,"msg":"登录成功!","rsData":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOiJhZG1pbiIsIkV4cGlyZXMiOiIyMDI0LTA0LTEwVDAxOjUxOjUwLjk5NDgxNzQrMDA6MDAifQ.eYJovquJFezVhfdLp-Hro2vnMoQsUwgXLkYcZSYEy7U"}

测试解密

解密成功

⭐️JwtBearer

9、添加NuGet包Microsoft.AspNetCore.Authentication.JwtBearer

10、在appsettings.json中添加JWT配置节点

  "JWT": {
    "SecKey": "im6666666!#@$%@%^^&*(~Czmjklneafguvioszb%yuv&*6WVDf5dw#5dfw6f5w6faW%FW^f5wa65f^AWf56", //密钥
    "Issuer": "im666", //发行者
    "ExpireSeconds": 7200 //过期时间 2h
  },

11.添加jwt类


    using Microsoft.IdentityModel.Tokens;
    using System.Diagnostics;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Text;

namespace webapijwttest.Models
{
    /// <summary>
    /// 授权JWT类
    /// </summary>
    public class JwtHelper2
        {
            private readonly IConfiguration _configuration;
            /// <summary>
            /// Token配置
            /// </summary>
            /// <param name="configuration"></param>
            public JwtHelper2(IConfiguration configuration)
            {
                _configuration = configuration;
            }
            /// <summary>
            /// 创建Token 这里面可以保存自己想要的信息
            /// </summary>
            /// <param name="username"></param>
            /// <param name="mobile"></param>
            /// <returns></returns>
            public string CreateToken(string username, string mobile)
            {
                try
                {
                    // 1. 定义需要使用到的Claims
                    var claims = new[]
                    {
                    new Claim("username", username),
                    new Claim("mobile", mobile),
                    /* 可以保存自己想要信息,传参进来即可
                    new Claim("sex", "sex"),
                    new Claim("limit", "limit"),
                    new Claim("head_url", "xxxxx")
                    */
                };
                    // 2. 从 appsettings.json 中读取SecretKey
                    var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                    // 3. 选择加密算法
                    var algorithm = SecurityAlgorithms.HmacSha256;
                    // 4. 生成Credentials
                    var signingCredentials = new SigningCredentials(secretKey, algorithm);
                    // 5. 根据以上,生成token
                    var jwtSecurityToken = new JwtSecurityToken(
                        _configuration["Jwt:Issuer"],    //Issuer
                        _configuration["Jwt:ExpireSeconds"],  //ExpireSeconds
                        claims,                          //Claims,
                        DateTime.Now,                    //notBefore
                        DateTime.Now.AddSeconds(30),     //expires
                        signingCredentials               //Credentials
                    );
                    // 6. 将token变为string
                    var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
                    return token;
                }
                catch (Exception)
                {
                    throw;
                }
            }
            /// <summary>
            /// 获取信息
            /// </summary>
            /// <param name="jwt"></param>
            /// <returns></returns>
            public static string ReaderToken(string jwt)
            {
                var str = string.Empty;
                try
                {
                    //获取Token的三种方式
                    //第一种直接用JwtSecurityTokenHandler提供的read方法
                    var jwtHander = new JwtSecurityTokenHandler();
                    JwtSecurityToken jwtSecurityToken = jwtHander.ReadJwtToken(jwt);
                    str = jwtSecurityToken.ToString();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                return str;
            }
            /// <summary>
            /// 解密jwt
            /// </summary>
            /// <param name="jwt"></param>
            /// <returns></returns>
            public string JwtDecrypt(string jwt)
            {
                StringBuilder sb = new StringBuilder();
                try
                {
                    JwtSecurityTokenHandler tokenHandler = new();
                    TokenValidationParameters valParam = new();
                    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                    valParam.IssuerSigningKey = securityKey;
                    valParam.ValidateIssuer = false;
                    valParam.ValidateAudience = false;
                    //解密
                    ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,
                            valParam, out SecurityToken secToken);
                    foreach (var claim in claimsPrincipal.Claims)
                    {
                        sb.Append($"{claim.Type}={claim.Value}");
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                return sb.ToString();
            }
        }
}

12.Program.cs注册JWT服务

#region JWT服务
// 注册JWT服务
builder.Services.AddSingleton(new JwtHelper2(builder.Configuration));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true, //是否验证Issuer
        ValidIssuer = builder.Configuration["Jwt:Issuer"], //发行人Issuer
        ValidateAudience = false, //是否验证Audience      
        ValidateIssuerSigningKey = true, //是否验证SecurityKey
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecKey"])), //SecurityKey
        ValidateLifetime = true, //是否验证失效时间
        ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
        RequireExpirationTime = true,
    };
}
);
#endregion

添加swagger authorization


builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web API", Version = "v1" });
    //开启注释
    var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);//需要 生成 目录生成XML
    c.IncludeXmlComments(xmlPath, true);
    // 配置 JWT Bearer 授权
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer"
    });
    var securityScheme = new OpenApiSecurityScheme
    {
        Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
    };
    var securityRequirement = new OpenApiSecurityRequirement { { securityScheme, new string[] { } } };
    c.AddSecurityRequirement(securityRequirement);




});


var app = builder.Build();


//启用验证中间件
app.UseAuthentication();
app.UseAuthorization();

13.添加jwt测试api

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity.Data;
using Microsoft.AspNetCore.Mvc;
using webapijwttest.Models;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace webapijwttest.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class Jwt2Controller : ControllerBase
    {
        private readonly JwtHelper2 _jwt;
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="jwtHelper"></param>
        public Jwt2Controller(JwtHelper2 jwtHelper)
        {
            _jwt = jwtHelper;
        }
        /// <summary>
        /// 获取Token
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetToken(LoginRs user)
        {
            //参数验证等等....
            if (string.IsNullOrEmpty(user.UserId))
            {
                return Ok("参数异常!");
            }
            //这里可以连接mysql数据库做账号密码验证
            //这里可以做Redis缓存验证等等
            //这里获取Token,当然,这里也可以选择传结构体过去
            var token = _jwt.CreateToken(user.UserId, user.PasswordMD5);
            //解密后的Token
            var PWToken = _jwt.JwtDecrypt(token);
            return Ok(token + "解密后:" + PWToken);
        }
        /// <summary>
        /// 获取自己的详细信息,其中 [Authorize] 就表示要带Token才行
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public IActionResult GetSelfInfo()
        {
            //执行到这里,就表示已经验证授权通过了
            /*
             * 这里返回个人信息有两种方式
             * 第一种:从Header中的Token信息反向解析出用户账号,再从数据库中查找返回
             * 第二种:从Header中的Token信息反向解析出用户账号信息直接返回,当然,在前面创建        Token时,要保存进使用到的Claims中。
            */
            return Ok("授权通过了!");
        }
    }
}

调用

检测控制器

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using webapijwttest.Models;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace webapijwttest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private ILogger<AuthController> _logger = null;
        private JwtHelper2 _iJWTService = null;
        private readonly IConfiguration _configuration;

        public AuthController(ILogger<AuthController> logger, JwtHelper2 jWTService, IConfiguration configuration)
        {
            this._logger = logger;
            _iJWTService = jWTService;
            _configuration = configuration;
        }

        [Route("Get")]
        [HttpGet]
        public IEnumerable<int> Get()
        {//未加授权认证
            return new List<int>() { 1, 3, 5, 7, 9 };
        }

        [Route("GetData")]
        [HttpGet]
        [Authorize]
        public List<object> GetData()
        {//添加了授权认证,需要使用token
            return new List<object>() { new { userName = "123", remark = "1234" } };
        }

        [Route("Login")]
        [HttpGet]
        public string Login(string name, string password)
        {
            if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(password))
            {
                string token = this._iJWTService.CreateToken(name,password);
                return JsonConvert.SerializeObject(new { result = true, token });
            }
            else
            {
                return JsonConvert.SerializeObject(new { result = false, token = "" });
            }
        }


    }
}

调用

把token放进 

测试GetData

当超过时间调用则GetData失败

END🐟🐟🐟

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

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

相关文章

Missing artifact org.opencv:opencv:jar:4.10.0 [opencv-4.10.0.jar]

Missing artifact org.opencv:opencv:jar:4.10.0 [opencv-4.10.0.jar] https://mvnrepository.com/artifact/org.opencv/opencv 根本就没有 找了个旧项目的opencv-410.jar修改下opencv-4.10.0.jar放到目录下面就好了 D:\localRepository\org\opencv\opencv\4.10.0 OpenCV-C…

【Spring高级】Spring Boot启动过程

目录 SpringApplication new 分析源码分析步骤演示primarySources和Sources应用类型webApplicationTypesetInitializers设置容器初始化器setListeners设置监听器主类推断 SpringApplication run 分析主要步骤步骤演示事件发布容器相关执行 runner准备EnvironmentEnvironmentPos…

【MATLAB源码-第45期】基于matlab的16APSK调制解调仿真,使用卷积编码软判决。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 16APSK调制解调 16APSK (16-ary Amplitude Phase Shift Keying) 是一种相位调制技术&#xff0c;其基本思想是在恒定幅度的条件下&#xff0c;改变信号的相位&#xff0c;从而传送信息。 - 调制&#xff1a;在16APSK中&am…

Github 2024-04-12 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6TypeScript项目2Cuda项目1C++项目1C项目1HTML项目1Jupyter Notebook项目1JavaScript项目1Python - 100天从新手到大师 创建周期:22…

书生·浦语大模型实战营 | 第3次学习笔记

前言 书生浦语大模型应用实战营 第二期正在开营&#xff0c;欢迎大家来学习。&#xff08;参与链接&#xff1a;https://mp.weixin.qq.com/s/YYSr3re6IduLJCAh-jgZqg 第三堂课的视频链接&#xff1a;https://www.bilibili.com/video/BV1QA4m1F7t4/ 本次笔记是学习完第三堂课…

视频秒播优化实践

本文字数&#xff1a;2259字 预计阅读时间&#xff1a;10分钟 视频起播时间&#xff0c;即首帧时间&#xff0c;是视频类应用的一个重要核心指标&#xff0c;也是影响用户观看体验的核心因素之一。如果视频要加载很久才能开始播放&#xff0c;用户放弃播放甚至离开 App 的概率都…

影响小程序SSL证书收费标准的因素有哪些?

在当今互联网时代&#xff0c;移动应用发展日新月异&#xff0c;小程序逐渐成为广大企业和个人开发者的心仪之选。然而&#xff0c;伴随小程序的广泛应用&#xff0c;安全问题和用户信任显得尤为关键。为了确保小程序的信息传输安全&#xff0c;SSL证书成为了一项基础配置。那么…

探索Web3的奇迹:数字时代的新前景

在数字化时代的潮流中&#xff0c;我们不可避免地迎来了一个全新的篇章——Web3时代的到来。在这个时代中&#xff0c;区块链技术作为数字化世界的核心&#xff0c;正在重塑着我们的生活方式、经济模式以及社会结构。在Web3时代&#xff0c;我们将目睹着一个以去中心化、透明化…

MS7336MA高清 HD/全高清 FHD 可选择视频运放与视频同轴线控解码

产品简述 MS7336MA 是一颗集成单通道视频放大器与视频同轴线控解 码为一体的芯片&#xff0c;它内部集成 6dB 增益轨到轨输出驱动器以及 10 阶滤波器&#xff0c;允许同一个输入信号在 -3dB 带宽 35MHz 和 55MHz 之间进行选择控制。视频同轴线控解码内部集成一颗高…

原型模式:复制对象的智能解决方案

在软件开发过程中&#xff0c;对象的创建可能是一个昂贵的操作&#xff0c;特别是当对象的初始化包括从数据库加载数据、进行IO操作或进行复杂计算时。原型模式是一种创建型设计模式&#xff0c;它通过复制现有的实例来创建新的对象实例&#xff0c;从而避免了类初始化时的高成…

QQ 邮箱使用 SMTP 发送邮件报错:550 The From header is missing or invalid

文章目录 场景描述问题排查根据提示查看原因查看封装的 message 个人简介 场景描述 QQ 邮箱使用 SMTP 发送邮件报错&#xff1a;550 The From header is missing or invalid&#xff1a; 失败原因&#xff1a;(550, bThe "From" header is missing or invalid. Ple…

6. Bean 的作用域和生命周期

Spring Framework的主要功能是用来存储和读取Bean&#xff0c;Bean于Spring框架的地位可见一斑。本节的目的就是从作用域和生命周期的角度更加深入了解一下Bean对象。 1. Bean的作用域 首先我们来学习一下Bean的作用域&#xff0c;源码位置&#xff1a;bean_scope 1.1 作用域…

iMazing如何备份手机资料 iPhone的资料可以传到iPad里吗 iphone备份到mac 苹果导入备份

在当今信息化快速发展的时代&#xff0c;手机已经成为我们生活中不可或缺的一部分。随着资料的积累&#xff0c;备份手机数据成了一个重要的问题。本文将介绍iMazing如何备份手机资料&#xff0c;并为大家解答“iPhone的资料可以传到iPad里吗”这一问题。这不仅可以帮助你有效管…

mybaits(8)-缓存机制

缓存机制 1、mybatis缓存2、一级缓存2.1 开启一级缓存2.2 一级缓存失效 3、二级缓存3.1 开启二级缓存3.2 二级缓存什么时候失效3.3 二级缓存的相关配置 4、MyBatis集成EhCache 1、mybatis缓存 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高…

最齐全,最简单的免费SSL证书获取方法——实现HTTPS访问

一&#xff1a;阿里云 优势&#xff1a;大平台&#xff0c;在站长中知名度最高&#xff0c;提供20张免费单域名SSL证书 缺点&#xff1a;数量有限&#xff0c;并且只有单域名证书&#xff0c;通配符以及多域名没有免费版本。并且提供的单域名证书只有三个月的期限。 二&#…

v1.9.2-httpsok快速申请免费SSL证书

v1.9.2-&#x1f525;httpsok快速申请免费SSL证书 介绍 httpsok 是一个便捷的 HTTPS 证书自动续签工具&#xff0c;专为 Nginx 、OpenResty 服务器设计。已服务众多中小企业&#xff0c;稳定、安全、可靠。 一行命令&#xff0c;一分钟轻松搞定SSL证书自动续期 更新日志 V1…

【vue】购物车案例优化

对 购物车案例 进行优化 用watch实现全选/取消全选用watch实现全选状态的检查用computed计算总价格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1&#xff09;zk集群中的角色 Zookeeper集群中的节点有三个角色&#xff1a; Leader&#xff1a;处理集群的所有事务请求&#xff0c;集群中只有一个LeaderFollwoer&#xff1a;只能处理读请求&#xff0c;参与Leader选举Observer&#xff1a;只能处理读…

HashMap部分底层源码解析

哈希表的物理结构 HashMap底层都是哈希表&#xff08;也称散列表&#xff09;&#xff0c;线程不安全&#xff0c;其中维护了一个长度为2的幂次方的Entry类型的数组table&#xff0c;数组的每一个索引位置被称为一个桶(bucket)&#xff0c;你添加的映射关系(key,value)最终都被…

clickhouse深入浅出

基础知识原理 极致压缩率 极速查询性能 列式数据库管理 &#xff0c;读请求多 大批次更新或无更新 读很多但用很少 大量的列 列的值小数值/短字符串 一致性要求低 DBMS&#xff1a;动态创建/修改/删除库 表 视图&#xff0c;动态查/增/修/删&#xff0c;用户粒度设库…