记C#优化接口速度过程
前提摘要
首先这个项目是接手的前一任先写的项目,接手后,要求对项目一些速度相对较慢的接口进行优化,到第一个速度比较慢的接口后,发现单接口耗时4-8秒,是的,请求同一个接口,在参数不变的情况下,会出现浮动的时长,这种,之前我在其他项目里面也遇到过,第一种是因为有其他用户在操作其他比较卡的接口时,或者导出报表时,造成接口卡顿的拥堵,这种情况没有办法去排查,只能一一把接口优化好,速度才能提上来**,第二种想到的是检测服务,如果服务跑的时候间隔时间较短**,然后又有大量的查询之类的,可能也会造成整体性能的低下,这种可以排查,检查服务确实有一分钟跑一次的服务,但是,查询不大,按理来说,应该痛点不是在这里
随后对该接口进行优化,首先是对数据库查询类的代码进行优化,将查询语句一一挑出来,之后再放到数据库中去排查查询速度比较慢的查询,但是未发现查询比较慢的查询,于是就只能先把缺掉的索引先补上,在检查数据库查询类的代码的时候,发现这个接口存在多次连接数据库查询数据,大概有20-30次,很明显是个隐患,这个地方肯定会有拖累速度,考虑到重写的话,首先是不熟悉业务流程,第二是可能需要花费大量时间,所以还是争取在不改变原来的逻辑下,去给接口进行优化,所以查询多次的问题就先放一放了,随后我给重点查询的地方添加上了计时,想通过此方法来找出耗时比较明显的查询再针对性的去进行优化
Stopwatch watch = new Stopwatch();
watch.Start();
//代码
watch.Stop();
//获取检测时长1
watch.ElapsedMilliseconds
watch.Start();
//代码
watch.Stop();
//获取检测时长2
watch.ElapsedMilliseconds
通过Stopwatch很快就发现
整个检测时间下来,整个接口跑完,都不到200ms,我觉得很奇怪,既然接口整体完成速度不到200ms,为何返回给postman的速度达到了惊人的几秒钟,此时我怀疑Stopwatch不准确,于是在代码开始前和开始后都加上了datetime.now,但是显示时间也很短
猜测1:计时不准
猜测2:返回json给前端的时候,时间耗费了很长
猜测1没有办法求证,猜测2其实做了那么多项目,其实也没有遇到,而且感觉这个接口返回的json也没有那么离谱,随后就只能抱着试一试的态度,设定了以下几组返回的json,以及他们最终测试的结果
第一种 返回原来的json 结果:几秒
第二种 返回一个字符串 结果:100-200毫秒
第三种 返回原来的json,但是减少一些很长的对象 结果:几秒
第四种 返回的对象再包一层 结果:几秒
第五种 不使用框架的json返回方法,自定义json返回方法 结果:几秒
很显然第二种的出现,让我认为json返回就是接口超时的最大原因,这里我只能去猜测
第一种 这里我只能去猜测是不是服务器的内存不够,造成的返回json时这么慢
第二种 会不会是c#识别到我没有用上面代码中的参数,所以它自己省略了上面一些代码的逻辑,直接就返回了字符串,但是日志记录到了每个节点的计时,而且这个结果跟一直计时的也对的上,那就只能往下求证
然后把返回的json最小化,这时候就用到了json压缩
后端代码
//data为需要转换的数据
public string GetJsonData<T>(T data)
{// 序列化数据为JSONstring json = JsonConvert.SerializeObject(data);// 如果需要压缩using (var memoryStream = new MemoryStream()){using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))using (var streamWriter = new StreamWriter(gzipStream)){streamWriter.Write(json);}return Convert.ToBase64String(memoryStream.ToArray());}
}
vue
npm install pako
import pako from 'pako'
// b64Data-->传入加密的数据进行解密
function unzip (b64Data) {let strData = atob(b64Data)// Convert binary string to character-number arrayconst charData = strData.split('').map(function (x) { return x.charCodeAt(0) })// Turn number array into byte-arrayconst binData = new Uint8Array(charData)// // unzipconst data = pako.inflate(binData)// Convert gunzipped byteArray back to ascii string:strData = String.fromCharCode.apply(null, new Uint16Array(data))return strData
}// 加密
function zip (str) {if (typeof str !== 'string') {str = JSON.stringify(str)}const binaryString = pako.gzip(str, { to: 'string' })return btoa(binaryString)
}这种会中文乱码,需要改一下let strData = atob(拿到的数据)
const charData = strData.split('').map(function (x) { return x.charCodeAt(0) })
const binData = new Uint8Array(charData)
strData = pako.inflate(binData,{to: 'string'})
//转换为json对象
ret.data = JSON.parse(strData);
这样整个压缩就结束了,3.2k的字符大概能压到2.几K,三分之一吧,至于查询速度,丝毫没有减少,那只能再看看,能不能继续减少json中的字符,如果这条路行不通的话
1.后面可能会把查询修改为存储过程
2.重构数据结构,优化查询频率之类的
整个过程下来,其实测试站速度很快,慢的也就是正式站,但是两个服务器的配置不同,这个没法横向比较,测试站数据量也没有正式站多,而且测试站的服务应该不是一直在跑的
破案了
破案了,是上一任小伙伴把一个实体的扩展方法内,返回字段的时候,做了很慢的查询,之前没发现是因为,之前只是查询了这张表,但是没有用这个字段,但是在返回json的时候,返回的是整个实体,导致它会去拿所有的字段,包括扩展类中的那个很慢查询的字段,所以,会导致看起来好像是json返回很慢的感觉,也算是个坑吧
相关文章:

记C#优化接口速度过程
前提摘要 首先这个项目是接手的前一任先写的项目,接手后,要求对项目一些速度相对较慢的接口进行优化,到第一个速度比较慢的接口后,发现单接口耗时4-8秒,是的,请求同一个接口,在参数不变的情况下…...

windows环境如何运行python/java后台服务器进程而不显示控制台窗口
1.通常我们在windows环境下使用Java或Python语言编写服务器程序,都希望他在后台运行,不要显示黑乎乎的控制台窗口: 2.有人写了一个bat文件: cd /d D:\lottery\server && python .\main.py 放到了开机自启动里,可是开机的…...

记周末百度云防御CC攻击事件
今天一早,收到百度智能云短信提醒,一位客户的网站遭遇了CC攻击。 主机吧赶紧登陆客户网站查看,是否正常,看是否需要通知客户。 结果打开正常,看情况并没什么影响,那就等攻击结果了再看吧。 下午的时候&am…...
vue中v-bind控制class和style
当使用v-bind指令控制class和style时,可以通过动态绑定的方式根据不同的条件来添加或移除class,以及改变元素的样式。 1. 控制class 通过v-bind:class可以动态绑定class属性。可以使用对象语法、数组语法或者计算属性来实现。 对象语法:使用…...
【面试经典150题】【双指针】392. 判断子序列
题目链接 https://leetcode.cn/problems/is-subsequence/?envTypestudy-plan-v2&envIdtop-interview-150 题解思路 首先如果s的长度大于t的长度,那么s肯定不是t的子序列如果s的长度等于t的长度,那么st的情况下s才是t的子序列如果s的长度小于t的长…...

禁用PS/Photoshop等一系列Adobe旗下软件联网外传用户数据操作
方案一: 下载火绒杀毒,在联网请求上禁用Adobe软件的联网请求,甚至还可以额外发现哪些是它要想要偷偷摸摸干的。 方案二: 最后注意: 用盗版软件只是获得了使用权!...
C语言猜输赢游戏
目录 开头游戏的程序游戏的流程图结尾 开头 大家好,我叫这是我58,现在,请你看一下下面的游戏程序。 游戏的程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <Windows.h> int main() {int i 1;int ia 0…...
Rust 异步 trait 的实现困难
在 Rust 中,异步编程是使用 async/await 语法来实现的。与传统的同步编程不同,异步编程涉及到的特性较多,其中一个重要的特性是异步 trait。 异步 trait 是具有异步方法的 trait。在 Rust 中,trait 方法默认是同步的,…...

腾讯云和windows11安装frp,实现内网穿透
一、内网穿透目的 实现公网上,访问到windows上启动的web服务 二、内网穿透的环境准备 公网服务器、windows11的电脑、frp软件(需要准备两个软件,一个是安装到公网服务器上的,一个是安装到windows上的) frp下载地址下载版本 1.此版本(老版…...

Solidity智能合约事件(event)
文章目录 Solidity智能合约事件(event)什么是event事件event有什么作用日志内容位于区块链的什么地方?【重要】以太坊交易获取如何在 Solidity 中使用事件?参考 Solidity智能合约事件(event) 什么是event EVM有一个日志功能,用于将数据“写…...

第2章 Rust初体验7/8:错误处理时不关心具体错误类型的下划线:提高代码可读性:猜骰子冷热游戏
讲动人的故事,写懂人的代码 2.6.6 用as进行类型转换:显式而简洁的语法 贾克强:“大家在查看Rust代码时,可能会注意到这一句。在这里,如果我们不使用as i32,编译器会报错,因为它在u32中找不到abs()方法。这是因为prev和sum_of_two_dice都是u32类型,u32类型并不支持abs(…...

大话C语言:第24篇 预处理
1 C语言编译流程 C语言的编译流程包括: 预编译:将.c 中的头文件展开、宏展开,生成的文件是.i 文件。gcc指令:gcc -E file.c -o file.i 编译:将预处理之后的.i 文件生成 .s 汇编文件。gcc指令:gcc -S file…...
React如何配置路由
ReactTs配置路由 安装依赖 npm i react-router-dom在routers下面创建index.tsx import { RouteObject } from react-router-dom import React from react import PageA from /views/PageA import PageB from /views/PageB const routes: RouteObject[] [{path: /,element: …...
MAC使用初体验+入门
之前从来没有使用过MAC,这次拿到了一个 不得不说MAC度过适应期后用起来很舒服,续航长,触控板舒服,轻薄无比 我前期过度的时候记录的一部分快速指南,掌握如下一些电脑常识 可以做到正常使用了 基本操作 在 Mac 上使用桌…...

Go TOKEN机制与跨域处理方式
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...
JavaScript 的运行
语法分析预编译解释执行 1.语法分析 语法分析是 JavaScript 引擎处理代码的第一步。 在这个阶段,引擎将源代码字符串分解成一个个的词素(token),这些词素是语言中有意义的最小单元,如关键字、变量名、操作符等。 语…...

园区地图导航系统:技术原理、部署方案与智能化应用解析
随着智能化时代的到来,园区管理面临诸多挑战。维小帮园区地图导航系统,采用前沿技术,为园区提供全面的导航解决方案,极大提升了园区管理效率和用户体验。 一、园区地图导航系统的功能特点 维小帮园区地图导航系统,以其…...

【数据结构】第十六弹---C语言实现希尔排序
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、希尔排序( 缩小增量排序 ) 1.1、预排序实现 1.2、希尔排序代码实现 1.3、代码测试 1.4、时空复杂度分析 1.5、性能比较 总结 上一弹我们…...

用Python向Word文档添加页眉和页脚
用Python向Word文档添加页眉和页脚 添加页眉和页脚效果代码 添加页眉和页脚 在本文中,我们将用python向文档中添加页眉和页脚。 效果 添加前的文档: 添加页眉和页脚后: 代码 from docx import Documentdef add_header_footer(doc_path…...

REST风格
黑马程序员Spring Boot2 文章目录 1、REST简介1.1 优点1.2 REST风格简介1.3 注意事项 2、RESTful入门案例 1、REST简介 1.1 优点 隐藏资源的访问行为,无法通过地址的值对资源适合中操作书写简化 1.2 REST风格简介 按照RST风格访问资源时使用行为动作区分对资源进…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...