在 Vue3 中使用 SVG 图标

图标是每个网站几乎都会用到的东西,下面我介绍一种在 vite 和 vue3 中使用 SVG 图标的方法。 unplugin-icons unplugin-icons 是一款按需加载图标的插件 安装 npm i unplugin-icons -D 配置 复制图标文件到项目中 我们将 SVG 图标放在 src/assets/icons 目录下面,我这里是把 vue 和 vite 的图标拷贝到了里面(因为我不会画也懒得画) . ├── .gitignore ├── index.html ├── package.json ├── package-lock.json ├── public │ └── vite.svg ├── README.md ├── src │ ├── App.vue │ ├── assets │ │ ├── icons │ │ │ ├── vite.svg │ │ │ └── vue.svg │ │ └── vue.svg │ ├── main....

2024年4月3日

如何使用OpenSSL创建自签名证书

创建 CA 证书 生成 CA 私钥 openssl genrsa -out ca.key 2048 虽然标题是生成私钥,但其实是生成密钥对,公钥和私钥都保存在文件中,可以通过以下指令查看公钥:openssl rsa -pubout -in ca.key 使用 CA 私钥生成 CA 证书 openssl req -x509 -new -nodes -key ca.key -days 36500 -out ca.crt 会提示你输入以下内容: Country Name (2 letter code) [AU]: CN State or Province Name (full name) [Some-State]: SC Locality Name (eg, city) []: CD Organization Name (eg, company) [Internet Widgits Pty Ltd]: HOME Organizational Unit Name (eg, section) []: LAB Common Name (e....

2023年12月17日

在K3s中配置使用NVIDIA GPUS

安装 NVIDIA 驱动 略 安装成功后可使用nvidia-smi命令查看驱动版本和 cuda 版本 $ nvidia-smi Thu Oct 12 11:29:15 2023 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 470.161.03 Driver Version: 470.161.03 CUDA Version: 11.4 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA A10-4Q On | 00000000:00:07.0 Off | N/A | | N/A N/A P0 N/A / N/A | 128MiB / 3932MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+ 安装 nvidia-container-runtime 添加 Apt 仓库 curl -fsSL https://nvidia....

2023年10月12日

C#中的可为空泛型返回值

当在 C# 8.0 中启用 NRT(Nullable Reference Types)时,代码中的 null 引用检查会得到加强,以帮助开发人员更好地识别和处理可能的空引用异常。在这种情况下,使用 T? 表示可空类型,其中 T 可以是引用类型或值类型。但是,如果使用 where T : struct 限定类型参数 T 为值类型,则 T? 表示 Nullable<T>。 var a = GetA<int>(); var b = GetB<int>(); T? GetA<T>() { return default; } T? GetB<T>() where T:struct { return default; } 在上述代码中,GetA<T>() 方法返回类型为 T?,因为 T 没有被限定为值类型,所以 T? 表示可空类型 T。由于 int 是值类型,因此 GetA<int>() 返回 0,而不是 null。 相反,GetB<T>() 方法限定类型参数 T 为值类型,因此 T? 表示 Nullable<T>。由于 int 是值类型,因此 GetB<int>() 返回 null,而不是 0。...

2023年8月4日

在 ASP.NET Core 中使用 Serilog

添加 Serilog 包引用 $ dotnet add package Serilog.AspNetCore $ dotnet add package Serilog.Sinks.Async 通过上方指令我们添加了以下两个包: Serilog.AspNetCore Serilog.AspNetCore 是基于 Serilog 框架的一个扩展库,用于在 ASP.NET Core 应用程序中使用 Serilog 来记录日志。它提供了一些方便的方法来集成 Serilog 框架到 ASP.NET Core 应用程序中,并支持从请求上下文中自动提取一些默认的日志信息,例如 HTTP 请求方法、路径和响应状态码等。通过使用 Serilog.AspNetCore,您可以轻松地将高质量日志记录添加到您的 ASP.NET Core 应用程序中。 Serilog.Sinks.Async Serilog.Sinks.Async 是 Serilog 库中的一个 sinks 扩展,用于异步地将日志事件写入目标存储。通过使用 Serilog.Sinks.Async,您可以避免在应用程序中引入 IO 操作的性能损失,从而提高应用程序的整体性能。 配置 Serilog 支持使用 appsettings.json 进行配置 在 appsettings.json 根节点下新增 Serilog 节点来配置 Serilog { "Serilog": { // 引用的 Serilog 的 sink,这里使用了 console、file、async 三种 "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Async"], // Serilog 对于不同的 logger 进行最小记录级别的配置 "MinimumLevel": { // 默认为 Information "Default": "Information", "Override": { // 对于 Microsoft 和 System 命名空间下的 logger,级别为 Warning "Microsoft": "Warning", "System": "Warning" } }, // 日志输出配置 "WriteTo": [ // 将日志输出到 Console { "Name": "Console" }, // 将日志输出到 File,同时使用 Async wrapper,可以让日志以异步方式写入文件 { "Name": "Async", // 使用 Async wrapper 提高日志写入文件性能 "Args": { "configure": [ { "Name": "File", "Args": { "path": "Logs/log....

2023年5月8日

使用Filebeat Sidecar在Kubernetes中收集容器日志

当今时代,Kubernetes 已成为了容器编排的事实标准。但是,在处理容器日志时,需要一种高效而可靠的方式来将数据从容器发送到日志分析工具中进行分析。本文将介绍如何部署并使用 Filebeat 收集容器日志器,并将数据通过 Logstash 传输到日志聚合平台。本文的重点是 Filebeat 部署,有关 Logstash 的问题请阅读《如何使用 Logstash 将日志写入阿里云 SLS 服务》 简介 Filebeat Filebeat 是 Elastic 公司开源的、高性能的轻量级日志数据收集器,可以自动化地收集和汇总多种不同来源的日志数据,然后将其发送到 Elasticsearch 和 Logstash 等不同种类的日志分析工具中。Filebeat 的设计目标是为了方便用户在不同的场景中使用,同时确保运行的高效性和可靠性。 准备工作 首先我们需要一个可以产生日志的应用,假设该应用部署文件如下: apiVersion: apps/v1 kind: Deployment metadata: name: my-app labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: my-app:v1.0.0 ports: - name: web containerPort: 80 该应用会往容器的 /app/Logs/ 路径下输出多个日志文件,文件命名格式为 log<suffix>.txt 部署 Filebeat Sidecar 挂载日志目录 为了使 Filebeat 能够采集到 my-app 的日志,我们需要使用 volume 来挂载日志目录,这里选用 emptyDir 卷来挂载日志目录...

2023年4月25日

如何使用Logstash将日志写入阿里云SLS服务

当你的应用程序越来越大,日志的管理变得越来越困难。而将日志存储在云服务上是现代化应用中的一个不可忽视的方面。在云服务中,阿里云 SLS 是一个非常好的选择,它可以帮助你收集、存储和查询应用程序日志。但是,如何将应用程序的日志发送到阿里云 SLS 服务呢?今天,我们将使用 Logstash,一个流行的开源工具,来将我们的日志发送到阿里云 SLS 服务中。 简介 阿里云 SLS 服务 阿里云 SLS(云监控日志服务)是一种高可靠、高扩展性的日志服务,主要用于收集和实时处理来自服务器、应用程序和云产品的日志数据。 SLS 提供了实时的查询、统计和报警等功能,有助于用户更轻松地管理日志。 SLS 支持大规模的日志数据处理,可以通过多种方式上传日志数据,例如 SDK、API、SLS Agent、Logstash 等,使用 SLS 可以快速查询、分析和可视化日志数据,帮助用户更好地理解自己的应用环境。 Logstash Logstash 则是一款通用的日志收集工具,可以将来自不同来源的日志数据进行收集、处理、转换和传输。Logstash 可以与各种插件配合使用,从而实现更多功能。例如,用户可以使用 Logstash 的 input 插件来收集来自多个来源的日志数据,使用 filter 插件来解析、过滤和重构这些数据,最后使用 output 插件将处理后的数据发送到各种目的地,如 Elasticsearch、Kibana 等。 准备工作 创建阿里云 SLS 服务实例 略 安装 Logstash 本文使用的 Logstash 版本为 8.7.0(截至本文发布最新版) 阿里云官方文档介绍了如何安装 Logstash,但如果要在 K8s 中运行则需要进行一些其他操作: 构建带有 logstash-output-logservice 插件的 Logstash 镜像 编写 Logstash 配置文件 部署至 K8s 构建镜像 通过 Dockerfile 来构建包含 logstash-output-logservice 插件的 Logstash 镜像,文件内容如下:...

2023年4月24日

如何正确在 ASP.NET Core 中返回流

最近有位朋友说他在接口中使用 File(Stream stream, string contentType) 方法报错,报错内容是 2023-03-30 18:00:36.8882|ERROR|Microsoft.AspNetCore.Server.Kestrel|Connection id "OHMPHOM94BVEL", Request id "OHMPHOM94BVEL:00000004": An unhandled exception was thrown by the application. 大致推测是请求接口前或者接口后出的异常,也没有详细信息,于是要来了一份代码,代码(精简版)如下: // ExcelDocument.cs public class ExcelDocument { public static Stream GetFileStream() { using var fs = new FileStream("appsettings.json", FileMode.Open, FileAccess.Read); var ms = new MemoryStream(); fs.CopyTo(ms); return ms; } } // HomeController.cs [HttpGet("GetFile")] public IActionResult GetFile() { var stream = ExcelDocument.GetFileStream(); // 原本是application/vnd.ms-excel, 我这里写测试返回的appsettings.json就换了一下 return File(stream, "application/json"); } 这段代码看着没啥问题,我试着请求了一下,果然有报错,我的报错如下:...

2023年3月30日

从 K8s 的 Pod 中拷贝大文件

从 K8s 的容器中拷贝文件可以使用kubectl cp命令,但是对于较大的文件(100M 以上)可能就不是很好使了,拷贝过程经常会出现EOF错误 对于较大的文件,我是这样操作的: 压缩 通过压缩可以减小大文件的体积 tar -czvf largefile.tar.gz largefile 此操作也可以用于打包整个文件夹,以便达到拷贝文件夹的目的 分片 对于体积较大的文件,即使压缩后仍然有好几百 M,这时使用kubectl cp也不一定能够拷贝下来,所以需要对其分割 split -b 50M -d largefile.tar.gz largefile.tar.gz 此操作会将largefile.tar.gz按照 50M/每个文件的大小分割为多个文件,-d选项则是使用数字来作为后缀(默认是英文字母) 例如:largefile.tar.gz有 220M,则分割后会变为 largefile.tar.gz00 # 50M largefile.tar.gz01 # 50M largefile.tar.gz02 # 50M largefile.tar.gz03 # 50M largefile.tar.gz04 # 20M 拷贝 使用kubectl cp命令拷贝分割后的文件 kubectl cp <pod-name>:largefile.tar.gz00 largefile.tar.gz00 kubectl cp <pod-name>:largefile.tar.gz00 largefile.tar.gz01 kubectl cp <pod-name>:largefile.tar.gz00 largefile.tar.gz02 kubectl cp <pod-name>:largefile.tar.gz00 largefile.tar.gz03 kubectl cp <pod-name>:largefile.tar.gz00 largefile.tar.gz04 对于多个容器的 Pod,可以使用-c选项指定具体的容器 合并 使用cat命令合并多个文件 cat largefile....

2023年3月24日

Newtonsoft.Json 小技巧

Newtonsoft.Json 是一个非常受欢迎的 .NET JSON 框架 一般来说大部分用户用到的方法主要就是 JsonConvert.SerializeObject 和 JsonConvert.DeserializeObject 方法 前者用于将 .NET 对象 序列化为 JSON 字符串,后者则是将 JSON 字符串反序列化为 .NET 对象 下面我将讲述一些你可能用过或者没用过的一些小技巧 填充对象 我现在有一个 {"name":"fissssssh"} JSON 对象,当将它转为Dictionary<string,string>后,可以通过键名name获取属性值 然而这个 JSON 现在变成 {"Name":"fissssssh"}, 无法再通过键名 name 获取属性值 Dictionary 是支持替换键名比较器的,但是 JsonConvert.DeserializeObject 只会调用其无参构造函数 我们可以手动将 Dictionary 创建出来, 然后通过 JsonConvert.PopulateObject 方法将 JSON 字符串序列化并填充至指定对象,代码如下 var json = "{\"Name\":\"fissssssh\"}"; // 创建一个键名忽略大小写的字典对象 var dict = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase); JsonConvert.PopulateObject(json, dict); // 使用 name 获取 JSON 中的 Name 属性值 var name = dict["name"]; 从流进行反序列化 有些情况下我们需要反序列化来自网络请求或者文件中 JSON,它们通常是以流的形式持有,反序列化先将其读取为字符串,当 JSON 内容过大的时候会产生一个巨大的字符串对象,如果此操作比较频繁则会对性能产生比较大的影响...

2023年3月12日