我的 .NET Core 博客性能优化经验总结
我的 .NET Core 博客性能优化经验总结
点击上方蓝字关注“汪宇杰博客”
导语
去年8月,我用 .NET Core 重写了我的博客系统。经过一年多的优化,服务器响应速度从上线时候的 80ms 提高到了现在的 8ms,十倍提速。可惜由于部署在国外,自然不可抗力会导致中国用户晚上访问速度不稳定。本文分享网络正常的前提下,我做了哪些优化和提升,希望能帮到大家。
其实,在.NET Core之前,我的旧版博客系统是 .NET Framework写的,从2008年的 ASP.NET Web From 2.0 一直维护到2018年的 ASP.NET MVC5,曾经被人怀疑过:“别骗人了,.NET怎么可能这么快?” 。而如今,.NET Core 从本质上就已经比 .NET Framework 有了巨大的性能提升,甚至在不少测试下超过了Node、Go、Java。其实光看 benchmark 没太大的意义,大部分实际应用中性能问题并不在于语言和框架,而是由不佳的设计、错误的框架使用方法引起的。在 .NET Core 的实践过程中,我也学习和收获了很多,因此写下此文,分享我自己的性能优化经验。
没有银弹
首先,每个系统都是不同的。性能优化需要针对不同系统,不同业务场景,不同应用领域,不同用户种群,没有一个通用方法。比如我的博客,是内容站,交互少,大量情况都是各种姿势读数据,所以我要保证的是尽可能快的提升数据读取速度。而有些系统,比如电商,有远比内容站复杂的业务逻辑,还有秒杀等极端情况。比如国内阿里带队的“数据库不要有外键”,这是因为阿里的业务压力必须这么做,他们需要的是极端情况的写入速度,显然我的博客以及很多内容站没有这种场景,因此我依然可以用外键。所以,在开始之前,读者必须明白,软件设计是没有银弹的。我所列出的经验仅仅针对我自己的博客。大部分经验能应用在类似的内容站上,但不要盲目实践。同样是内容站,面对的用户群和压力也不一样,比如我的博客肯定无法和新浪、网易等比流量,所以优化的关键点和方法也不同。
分析和发现关键点
虽然我们在系统设计时会有一定的预判,比如哪些功能是用户最常用的,哪些请求会是最频繁的。但是上线之后用户的行为才是事实,有时候系统的表现会和我们的预期不一样。而且,随着时间的推移,用户的使用习惯可能会变,系统面临压力的部分也会改变。所以,我们需要记录和分析系统在实际使用过程中产生的数据和用户行为。而我所使用的Azure Application Insights就是一款极佳的APM工具。作为一个网站,性能是服务端(后台)和客户端(前台)共同决定的,Azure Application Insights可以同时收集后端API处理速度、数据库查询相应速度以及前端页面资源加载速度、JS执行速度等,也会自动分析出最慢的请求是哪些,系统最耗时的操作在哪个环节(前端、程序或数据库),甚至Azure SQL Database能根据实际使用情况自动推荐优化方案(比如哪里加何种索引等)。本文不讨论APM工具的使用。但是做性能优化的时候,必须针对实际用户产生的数据,分析以后去鉴别哪里需要优化。我的博客上线几个月后,我的分析如下:
1. 客户端性能开销在加载资源和过多的请求(前端库,博客文章配图)
2. 服务端性能开销在过多重复的SQL查询
3. 博客配图由后端从Azure Blob Storage中读取再返回前端产生双倍性能开销
前端实践
使用 bundle 避免过多请求
我相信大部分Web程序员都熟悉这一条建议,这也是最直接有效的前端性能提升方式。我们网站中通常要加载许多不同的库和资源,有图片,CSS,JS等。而浏览器大量的时间开销在于对这些资源发起请求,等待响应。即使你的文件很小,但是太多的请求数量会明显降低网页加载速度。因此很久之前业界就流行一种做法,即打包压缩资源文件,比如将多个JS文件打包压缩成一份,这样浏览器就只要发起一个请求,就能加载你网站所有需要的JS资源。
打包工具五花八门,可以根据自己的喜好选择。我博客使用的是 BuildBundlerMinifier ,它可以在编程和编译时完成打包:
其定义示例如下:
{
"outputFileName": "wwwroot/js/app/app-js-bundle.js",
"inputFiles": [
"wwwroot/lib/jquery/jquery.min.js",
"wwwroot/lib/jquery-validate/jquery.validate.min.js",
"wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js",
"wwwroot/lib/twitter-bootstrap/js/bootstrap.bundle.min.js",
"wwwroot/lib/jquery-qrcode/jquery.qrcode.min.js",
"wwwroot/lib/toastr.js/toastr.min.js",
"wwwroot/js/lazyload.js",
"wwwroot/js/app/moonglade-base.js",
"wwwroot/js/app/postslug.js",
"wwwroot/js/app/csrf.js",
"wwwroot/js/app/comments.js"
]
}
Js真的要放body最后吗?
这也是一条几乎Web程序员人尽皆知的原则。如果你将JS资源放在body最后加载,即
标签之前,那么浏览器会异步加载你的JS。如果按照传统方式将JS资源放在head标签里,那么浏览器必须加载完JS资源才开始渲染网页。
聪明的朋友可能了解,这一条在2019年已经不一定适用了。首先,我们可以通过添加defer标签来告诉浏览器,遇到这个JS,不要等加载完成再继续干活,你管你渲染网页,我管我加载:
不过defer的脚本还是会按顺序执行,这对于有依赖关系的JS资源十分重要,比如上面这段代码,即使007.js非常小,首先加载完成,它也必须等到996.js加载完成后才能执行。如果你想要谁先加载完,谁先执行的效果,把defer换成async即可,这种情况下你得保证你的JS之间没有依赖关系,没有依赖关系,没有依赖关系!!! 重要的说三遍!
可惜,由于我们控制不了用户使用的浏览器类型和版本,根据 Azure Application Insights 的后台统计,仍然有不少用户使用低版本的浏览器访问我的网站,它们并不认识 defer和 async。
所以目前,我博客的实践依然是JS尽量放body最后,但不是绝对!由于框架性质的JS文件必须完成加载才能正确渲染网页,因此我博客中它们还是放在head里,而用户代码我会放在body最后。优化性能的前提,一定是不要影响正常功能!所以,程序员看问题不要非黑即白,还是那句软件工程的老话:没有银弹。
如果你的网站没有低版本的客户端,那么可以尽量用 defer和 async。
使用 HTTP/2
启用HTTP2可以有效提高网络传输效率,根据该项调研(https://w3techs.com/technologies/details/ce-http2),截至2019年12月,全球大约有42.6%的网站已经升级到了HTTP2。其对于网络性能的提升主要在这几个方面:
降低延迟以提高网页加载速度:
(参考:https://en.wikipedia.org/wiki/HTTP/2)
而我的博客使用微软 Azure App Service 托管,可以点点鼠标一秒切换到 HTTP/2 ,而不用自己996 收福报:
如果你没有用 Azure,也不用担心,最新版 .NET Core 3.1 的kestrel 默认就打开了HTTP/2:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#http2-support
使用压缩
开启服务器端response压缩可以减小资源传输的体积,从而达到提升性能的目的。使用 ASP.NET Core 开发的网站,部署在Azure 上默认就会开启gzip,不需要自己996 去研究。我的博客采用的 App Service Plan 是 Windows Server 2016,上面的IIS启用了静态和动态资源压缩。
然而,如果你不幸没有使用 Azure ,那么自己稍微996 一下,在IIS上开启压缩也不难,可以点点鼠标就搞定,也可以通过Web.config开启(.NET Core部署在IIS下也认web.config),具体方法可以参考:https://docs.microsoft.com/en-us/iis/configuration/system.webserver/httpcompression/
如果你用的不是IIS,也没关系,再996一下,.NET Core自己也可以加response压缩:
https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-3.1
真的要用SPA吗?
2014年以后,随着SPA的兴起,Angular等框架逐渐成为了前端开发的主流。它们解决的问题正是提升前端的响应度,让Web应用尽量接近本地原生应用的体验。我也遇到过不少朋友有疑问,为啥我的博客不用angular写?是我不会吗?
其实并不那么简单。实际上我在公司的主要工作目前也是写angular,博客曾经的.NET Framework版的后台也用过angularjs以及angular2,经过一系列的实践表明,我博客这样的内容站用angular收益并不大。
其实这并不奇怪,在盲目选择框架之前,我们得注意一个前提条件:SPA框架所针对的,其实是Web应用 。而应用 的意思是重交互,即像Azure Portal或Outlook邮箱那样,目的是把网页当应用程来开发 ,这时候SPA不仅能提升用户体验,也能降低开发成本,何乐而不为?但是博客属于内容为主的网站,不是应用,要说应用也勉强只能说博客的后台管理可以是应用。博客前台唯一的交互就是评论、搜索 ,因此SPA并不适合这样的工作。这就像你要去菜场买菜,骑自行车反而比你开个坦克过去方便。
所以,程序员切记,看待问题不要非黑即白,不要觉得什么流行就一定适合所有项目 ,还是那个著名的软件工程原则:没有银弹!
在微软官方文档里也有同样的关于何时选择SPA,何时选择传统网站的参考:
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/choose-between-traditional-web-and-single-page-apps
“
You should use traditional web applications when:
Your application's client-side requirements are simple or even read-only.
Your application needs to function in browsers without JavaScript support.
Your team is unfamiliar with JavaScript or TypeScript development techniques.
You should use a SPA when:
Your application must expose a rich user interface with many features.
Your team is familiar with JavaScript and/or TypeScript development.
Your application must already expose an API for other (internal or public) clients.
”
后端实践
尽量避免Exception
.NET的Exception是一种特殊的类型,不管用户代码是否处理exception,只要产生,就会在CLR上有开销。所以尽量避免产生Exception,尤其是不要利用Exception控制程序流程,这一点通常在.NET的技术文章里都会提及。一个不正常利用Exception的例子是我曾经在公司代码里看见过类似这样判断输入的内容是否为数字的代码:
try
{
Convert.ToInt32(userInput);
return true;
}
catch (Exception ex)
{
return false;
}
而.NET其实可以这样写:
int.TryParse(userInput);
我相信大部分正常的.NET程序员都不会犯上面这种错误。这样的代码效率低下且不说,还容易炸毁IIS。IIS的应用程序池如果在短时间检测到大量CLR异常就会自爆重启并返回503,中断你的网站服务。
不过关于Exception的另一个争论点在于,是否需要为业务异常设计自己的Exception类型?也就是检查到非正常业务行为,到底返回Error Code还是直接抛出Exception再由上层处理 ?关于这点,我也没有确定的结论。目前我的实践是,仅对于非法输入抛出参数异常,业务上的错误不抛异常,例如文章被和谐后产生的404,不去设计比如 PostNotFoundException,这一点很关键,因为经常有无聊黑客新手使用自动化工具扫描我的博客是否有漏洞,而这些工具会批量请求例如wp-login.php之类的对于我博客来说不存在的资源,如果我设计成抛出Exception再返回404,那么会造成短时间内CLR上大量的异常,绝对会爆。
参考:https://devblogs.microsoft.com/cbrumme/the-exception-model/ 中“Performance and Trends”一节。
EF尽量使用AsNoTracking筛选只读数据
每个.NET群,都可以为Entity Framework vs Dapper吵一天。其实EF虽然在很多场景由局限,但并不那么差,只是想要用对,不产生性能问题,付出的学习成本相当高。但是既然入坑了,就最好把它用用对。而最常见的情况就是遇到只读数据,可以加上AsNoTracking() 。我博客大部分的场景都是只读数据,并且读取后直接处理好关联数据(Include) ,因此可以使用AsNoTracking()来断开EF对于对象的追踪,节省内存也提高性能。为了不每次手写AsNoTracking() 导致996,我在博客的存储层直接设置了默认参数:
public IReadOnlyList Get(ISpecification spec, bool asNoTracking = true)
{
return asNoTracking ?
ApplySpecification(spec).AsNoTracking().ToList() :
ApplySpecification(spec).ToList();
}
关于EF,我在2012年还写过一篇关于性能的文章,至今也适用于.NET Core,欢迎参考:
《Performance tips for Entity Framework》
另外,在最新的EF Core 3.x中,微软为了不被人骂EF性能差,直接默认禁止了client side evaluation,避免了忘写Include结果还开Lazy Load导致外键表被查询几百次的尴尬场面。
数据库DTU
我的博客采用Azure SQL数据库的DTU计量方式。请求频繁的时候会导致DTU耗尽,从而后续请求需要排队执行。所以首先优化的就是增加DTU容量,目前20个DTU基本管够。
而DTU是否够用可以直接在Azure的面板里看报表得到:
内存及缓存,减少数据库调用
计算机的内存是为了用,而不是为了省。程序要么牺牲空间换时间,要么牺牲时间换空间。合理使用内存做缓存,而不是每次都调用数据库,可以提高一段时间内的性能。特别是云端环境,数据库的调用通常是最花时间的环节(Application Insights里认为是dependency call)。即使不用内存缓存,也可以根据项目需要配置redis等产品。
在我博客里,缓存的使用随处可见。比如文章分类、Custom Page这种不经常更新的数据,就可以缓存起来,这样就不至于每次请求都去查询数据库。另外,像配置之类的数据,也建议设计成单例模式,网站启动时候加载完毕,不要每个请求都去数据库里重新读配置。这将极大的减少数据库的压力并提高网站响应速度。
var cacheKey = $"page-{routeName.ToLower()}";
var pageResponse = await cache.GetOrCreateAsync(cacheKey, async entry =>
{
var response = await _customPageService.GetPageAsync(routeName);
return response;
});
除了数据库,本地、远程图片或其他类型的文件也可以利用缓存来提高性能。
CDN
尽量用CDN服务静态资源,并配置pre-fetch,减少DNS解析次数。我的博客图片由于设计了抽象隔离,博客的配图并不是像访问静态资源那样直接输出到客户端,目前支持两种存储方式:Azure Blob、本地文件系统,不管哪种存储,都避免不了从对应位置读取图片,并返回给客户端显示,即使加上了服务器端缓存(MemoryCache),这个过程也依然对服务器有较大压力。
目前我选用的存储方式为Azure Blob。以前读取一张图片的过程是:
首次请求:服务器去Azure Blob拿图片,客户端再去网站服务器拿图片。
后续请求:Hit到memory cache,仅从网站服务器返回图片给客户端。
然而,即使后续请求不用经过Azure Blob,对Web服务器的请求还是必须存在的,这也是挺大的开销。于是,我通过CDN,让图片请求再也不经过我自己的Web服务器,而是直接访问Azure Blob。
于是现在,读取一张图片的过程是:
首次请求:CDN判断自己是否已经缓存了图片,如果没有,去Azure Blob里拿,并缓存起来。
首次请求:CDN判断自己是否已经缓存了图片,如果没有,去Azure Blob里拿,并缓存起来。
这样一来,用户阅读博客文章时产生的图片请求只会经过Azure CDN的服务器,不会对Web服务器造成压力。
另外,可以在网页 header 上加个 dns-prefetch ,指向CDN服务器域名:
这样浏览器就会提前解析CDN服务器的地址,进一步加快网页加载速度。
日志级别
很多程序员习惯本地和生产用同一份日志配置,而本地通常打开Debug、Trace等低等级日志以帮助我们的开发和测试工作,线上的产品是经过测试的相对稳定的发布版本,其实并不需要这些低等级日志,所有的事件都要记log的话会极大的影响应用性能。所以我的实践是生产环境只开Warning以上的日志级别 ,除非遇到刁钻问题需要收集详细爆炸数据,会临时开几个小时的Debug日志。
APM不要随便加profiler
这条建议和上面类似,APM工具通常提供了各种profiler,然而这一般都会影响性能。就算是Azure自己的Application Insights也是如此。所以除非程序出现需要996调查的爆炸事故,一般不建议打开这些profiler。
总结
以上是我目前使用到的提升博客性能的方法。但是性能优化没有完全通用的策略,需要根据不同系统,不同业务,不同压力来动态调整优化方案,总体思想即:减少不必要的调用与开销。但有时候也需要调整应用程序的部署架构,比如Azure可以加上Traffic Manager、Front Door,使用负载均衡功能。欢迎大家留言分享自己的想法,以及对本文的补充和建议!
你可能感兴趣的:(我的 .NET Core 博客性能优化经验总结)
OC语言多界面传值五大方式
Magnetic_h
ios ui 学习 objective-c 开发语言
前言在完成暑假仿写项目时,遇到了许多需要用到多界面传值的地方,这篇博客来总结一下比较常用的五种多界面传值的方式。属性传值属性传值一般用前一个界面向后一个界面传值,简单地说就是通过访问后一个视图控制器的属性来为它赋值,通过这个属性来做到从前一个界面向后一个界面传值。首先在后一个界面中定义属性@interfaceBViewController:UIViewController@propertyNSSt
我的烦恼
余建梅
我的烦恼。女儿问我:“你给学生布置什么作文题目?”“《我的烦恼》。”“他们都这么大了,你觉得他们还有烦恼吗?”“有啊!每个人都会有自己烦恼。”“我不相信,大人是没有烦恼的,如果说一定有的话,你的烦恼和我写作业有关,而且是小烦恼。不像我,天天被你说,有这样的妈妈,烦恼是没完没了。”女儿愤愤不平。每个人都会有自己的烦恼,处在上有老下有小的年纪,烦恼多的数不完。想干好工作带好孩子,想孝顺父母又想经营好自
2019-12-22-22:30
涓涓1016
今天是冬至,写下我的日更,是因为这两天的学习真的是能量的满满,让我看到了自己,未来另外一种可能性,也让我看到了这两年这几年的过程中我所接受那些痛苦的来源。一切的根源和痛苦都来自于人生,家庭,而你的原生家庭,你的爸爸和妈妈,是因为你这个灵魂在那一刻选择他们作为你的爸爸和妈妈来的,所以你得接受他,你得接纳他,他就是因为他的存在而给你的学习和成长带来这些痛苦,那其实是你必然要经历的这个过程,当你去接纳的
python os.environ_python os.environ 读取和设置环境变量
weixin_39605414
python os.environ
>>>importos>>>os.environ.keys()['LC_NUMERIC','GOPATH','GOROOT','GOBIN','LESSOPEN','SSH_CLIENT','LOGNAME','USER','HOME','LC_PAPER','PATH','DISPLAY','LANG','TERM','SHELL','J2REDIR','LC_MONETARY','QT_QPA
感赏日志133
马姐读书
图片发自App感赏自己今天买个扫地机,以后可以解放出来多看点书,让这个智能小机器人替我工作了。感赏孩子最近进步很大,每天按时上学,认真听课,认真背书,主动认真完成老师布置的作业。感赏自己明白自己容易受到某人的影响,心情不好,每当此刻我就会舒缓,感赏,让自己尽快抽离,想好的一面。感赏儿子今天在我提醒他事情时,告诉我谢谢妈妈对我的提醒我明白了,而不是说我啰嗦,管事情,孩子更懂事了,懂得感恩了。投射父母
我的黑历史
袖手围观有来有去
孩子同学与我们一起共进晚餐,俩孩子加我三个人。小同学是一个大方率性礼貌的小孩,我们也都非常喜欢。好了,回到正题上来让我把这个故事讲完。俩孩子都喜欢吃鱼,所以就发生了小孩子之间常会发生的事。我狠狠的盯了我家孩子,孩子表情有些狼狈。和孩子单独一起的时候,见她尚未释怀,并谴责我不该狠盯她,让她没面子。也许是她触动了我的童年往事吧。由此,一狠心,给她讲了一段埋藏心里极深的黑历史:我奶奶有四个儿子,四个儿子
509. 斐波那契数(每日一题)
lzyprime
lzyprime博客(github)创建时间:2021.01.04qq及邮箱:2383518170leetcode笔记题目描述斐波那契数,通常用F(n)表示,形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1给你n,请计算F(n)。示例1:输入:2输出:1解释:F(2)=F(1)+
读《人世间》有感
一0一
这个寒假,就如同朋友圈中的一段话:一闭眼,一睁眼假期还有5天,在一闭眼一睁眼假期还有12天;再一闭眼一睁眼假期还有20天;不敢睡,不敢睡啊……受疫情影响,这个假期变得漫长又煎熬,我也无时无刻不关注着疫情的变化。当然这样的一个假期,我还真得要感谢周翔,因为他有个爱看书的习惯,所以家里有不少他看过的书,可以让我随意挑选,因此也让我的假期不至于那么无所事事。这次我选了一本梁晓声的《人世间》,作为一名语文
Git常用命令-修改远程仓库地址
猿大师
Linux Java git java
查看远程仓库地址gitremote-v返回结果originhttps://git.coding.net/*****.git(fetch)originhttps://git.coding.net/*****.git(push)修改远程仓库地址gitremoteset-urloriginhttps://git.coding.net/*****.git先删除后增加远程仓库地址gitremotermori
万物难度不度己
边度512
你好,陌生人!你是否有过迷茫,在别人的面前自己却不曾展示!你是否自己承担着所有的痛苦,却又笑对人生!你是否在很多时候想找人诉说,翻开手机却发现,手机里面空无一人!你是否有很多事情想做,最后却因你自己拖延,最后发现自己什么都做不了!对没有错,我的名字就叫你是否!不要怀疑!不要悲伤!我们的生活可是还有很到要继续的呢!还有很多那个人,很多地方我们都没有去过!所以我们已经没有退路了!那就继续向前吧!加油!
398顺境,逆境
戴骁勇
2018.11.27周二雾霾最近儿子进入了一段顺境期,今天表现尤其不错。今天的数学测试成绩喜人,没有出现以往的计算错误,整个卷面书写工整,附加题也在规定时间内完成且做对。为迎接体育测试的锻炼有了质的飞跃。坐位体前屈成绩突飞猛进,估测成绩能达到12cm,这和上次测试的零分来比,简直是逆袭。儿子还在不断锻炼和提升,唯恐到时候掉链子。跑步姿势在我的调教下,逐渐正规起来,速度随之也有了提升。今晚测试的50
从0到500+,我是如何利用自媒体赚钱?
一列脚印
运营公众号半个多月,从零基础的小白到现在慢慢懂了一些运营的知识。做好公众号是很不容易的,要做很多事情;排版、码字、引流…通通需要自己解决,业余时间全都花费在这上面涨这么多粉丝是真的不容易,对比知乎大佬来说,我们这种没资源,没人脉,还没钱的小透明来说,想要一个月涨粉上万,怕是今天没睡醒(不过你有的方法,算我piapia打脸)至少我是清醒的,自己慢慢努力,实现我的万粉目标!大家快来围观、支持我吧!孩子
想明白这个问题,你才能写下去
文自拾
春节放假的时候,又有一天梦见她,第二天她冒着漫天大雪,傻傻地跑来见我。她说,见见傻傻的我,天很冷,心很暖。她回去后,我写了一篇文章,题目叫——从此梦中只有你。我们没在一起的很长一段时间里,她都在我的心底,一次次出现在我的梦里。我对她说,在一起之前,是胆小且闷骚,在一起之后,我变得不要脸了。不要脸的——去爱你。那文章没写完,火车上,给她看了。我有点小失望,花了好几个小时写,她分分钟就看完,很希望她逐
HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动
二挡起步
web前端期末大作业 web设计网页规划与设计 html css javascript dreamweaver 前端
Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线
其二
十八尾喵
你知道吗?图片发自App我今天知道了你有喜欢的人,不是我。心空空的,整个人都不是我的了。可,怎么办?还是要好好的活着,毕竟你喜欢的人,我不能杀,可是我可以杀其他喜欢你的人呀!也罢,此生无缘,来世再见。鱼干
没想到,真没想到
一棵落花的树
生活中,每一件小事都蕴藏着他的道理。有些令你意外,却能让你收到更为意外的结果。那一次,我真没想到的事,让我收获了爱。记忆的雨飘落下来,扰乱了我平静的心湖。那是一次数学考试,我破天荒地考了“99”分。我不禁沾沾自喜,这成绩我可不容易得到,妈妈一定会好好表扬我的。回到家,我想妈妈得意的报出成绩,妈妈只是淡淡的说:“嗯,等会儿试卷拿给我看看。”做完作业,我把试卷拿给了妈妈。只见妈妈捧着试卷,眯着眼睛盯着
嘿,谢谢你
小小玛拉沁
突然想对一个女孩子说,谢谢你!很久很久以前,总是觉得和你不会有太多交集,充其量也只是普通的舍友吧,毕竟有很多习惯,性格等方面相差甚远。其实特别感谢2017这一段经历和我遇见的人,只会慢吞吞的过自己生活的安小蜗是不会主动去结交朋友的,所以她来到了我的世界,让我在不知不觉中发现了自己太多太多的问题,而我正在逐渐去改变这些的习惯,成为更好的自己!我总是超级佩服她不管什么时候精力都超级旺盛,可以在上了一天
如何成为段子手
欣雅阅读
我是一个尬聊大师,与朋友聊天经常把话题聊死,留我一个人在群里,望着自己打下的最后一句话无语凝噎。看到风趣幽默的朋友与人聊天,很是艳羡,觉得自己何时才能成为这样的段子手呢?一、段子是什么?“段子”一词在百度百科上的解释:本是相声中的一个艺术术语,指的是相声作品中一节或一段艺术内容。我的理解:段子就是一些搞笑的故事或者笑话。二、为什么要会说段子?不知道大家有没有这样的朋友,本来很无趣的聚会,只要有他参
Python 实现图片裁剪(附代码) | Python工具
剑客阿良_ALiang
前言本文提供将图片按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。环境依赖ffmpeg环境安装,可以参考我的另一篇文章:windowsffmpeg安装部署_阿良的博客-CSDN博客本文主要使用到的不是ffmpeg,而是ffprobe也在上面这篇文章中的zip包中。ffmpy安装:pipinstallffmpy-ihttps://pypi.douban.com/simple代码不废话了,上代码
直返APP是什么?直返APP是干嘛的
氧惠帮朋友一起省
直返是一种电商购物模式,其核心特点是用户购买商品后可以获得直接返利。具体来说,用户在直返电商平台购买商品时,不仅可以获得商品本身的优惠,还可以获得一定的现金返利或者积分奖励。返利的金额可以提现到用户的账户余额,或者用于下次购物时抵扣。氧惠APP(带货领导者)——是与以往完全不同的抖客+淘客app!2023全新模式,我的直推也会放到你下面。主打:带货高补贴,深受各位带货团队长喜爱(每天出单带货几十万
那个严厉的启蒙老师
小米星的天空
本文参加鹏哥教师节征文活动我的启蒙老师李老师,大概是唯一动手打过我,但是我仍然很感恩的老师吧。李老师当年四十多岁,擅长珠心算教学,算是我们乡镇小学的王牌老师。李老师很严厉,不仅要骂学生,还要动手打人,他的大眼睛一瞪,全班同学都瑟瑟发抖。在九十年代,家长不像现在这样宠溺孩子。许多家长都跟老师说,管得严一点,不听话就给我打。那时候棍棒教育是很正常的,教室里的木质米尺,常常因为被用来打调皮男生的屁股而折
直返的东西正品吗?直返APP安全吗?直返是正规平台吗?
氧惠购物达人
亲们,你们是不是经常在直返APP上买东西呀?但是,你们有没有想过,里面的东西到底是不是正品呢?这个APP安全吗?它是不是一个正规的平台呀?别着急,今天我就来给大家揭秘一下!氧惠APP(带货领导者)——是与以往完全不同的抖客+淘客app!2023全新模式,我的直推也会放到你下面。主打:带货高补贴,深受各位带货团队长喜爱(每天出单带货几十万单)。注册即可享受高补贴+0撸+捡漏等带货新体验。送万元推广大
【无标题】达瓦达瓦
JhonKI
考研
博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️111❤️111111111111111总结11
上图为是否色发
JhonKI
考研
博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️111❤️111111111111111总结11
《大兴安岭猎人传说》今年最好看的东北鬼怪故事,很优秀
一部电影
《大兴安岭猎人传说》是最新上映于愚人节的网剧,别看是网剧却远超出我的个人预料。该片由民俗故事改编,这点就很吸引人,因为民俗故事口口相传,比那些编造而成的鬼故事更具有了真实性,网大做的电影还不错哦,如果可以我打四星好评。大兴安岭的故事我们经常听老人提起,那里有原始大森林,物产丰富,更流传着精灵怪物的传说。什么红黄白柳灰,出马仙、人参娃娃的故事层出不穷,以大兴安岭为背景的故事真不少。可很多鬼片看到最后
143234234123432
JhonKI
考研
博客主页:https://blog.csdn.net/2301_779549673欢迎点赞收藏⭐留言如有错误敬请指正!本文由JohnKi原创,首发于CSDN未来很长,值得我们全力奔赴更美好的生活✨文章目录前言111️111❤️111111111111111总结111前言111骗骗流量券,嘿嘿111111111111111111111111111️111❤️111111111111111总结11
2018-12-16
宝妈林秀云
2018年12月16日星期日天气晴本来今天是要参加读经班的,小宝贝昨天晚上突然发烧了,所以就没办法参加。同时今天也是小宝贝的生日,因为发烧她爸爸就不买蛋糕给她过生日了。就给她买了榴莲披萨当蛋糕。姐姐还为她做了生日贺卡,这个生日贺卡姐姐可是花了很长时间才完成的。吃完披萨准备上楼了,这时杨欣也想跟我们一起上楼,就被奶奶叫住说:“不要上楼了要准备睡觉了”。本来我想小宝贝可能会吵着跟杨欣一起玩。出乎我的意
《我的青葱岁月之缘来是你》 第二章 迎新晚会
思源思缘思怨
“怎么你也来了这里?”我愉快的问到,想着这是上天给的缘分吗?我还没去找他竟然就相遇了。那个让我开心的老乡。“你好,我也是舞蹈社的新人啊!”他说,笑起来回答我,眼睛弯弯的。“这么巧,我叫吴倩,你叫啥?”“我叫韩欢,你也是B市人吧,c中毕业的?”“我不是,我是f中的,不然肯定会认识你的”“是吗?以后多多关照了”他还冲我眨了眨眼睛。内心一阵悸动,这是……回到寝室,我兴奋的告诉我的室友这个事情,我再次觉得
每天都有“小感动”
河北张海霞
上次开学,在楼道值班儿的我,回到办公室后,发现我的办公桌上了一个小饭盒,打开一看,是自家腌的萝卜片,闻起来香香的,是哪位有心的孩子带来的?我猜测着……会不会是杨同学,记得开学第一天,她胃疼再加上低血糖,我曾陪她去医务室看病,并给她带回了早餐……还是李同学,那次她被别的同学欺侮,我为她主持公道。晚餐时间到了,我还带她去餐厅吃饭,引得同学们一阵羡慕……会不会是王同学,那次她眼睛不好,我陪她聊天,关心地
Python中深拷贝与浅拷贝的区别
yuxiaoyu.
转自:http://blog.csdn.net/u014745194/article/details/70271868定义:在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复
关于旗正规则引擎规则中的上传和下载问题
何必如此
文件下载 压缩 jsp 文件上传
文件的上传下载都是数据流的输入输出,大致流程都是一样的。
一、文件打包下载
1.文件写入压缩包
string mainPath="D:\upload\"; 下载路径
string tmpfileName=jar.zip; &n
【Spark九十九】Spark Streaming的batch interval时间内的数据流转源码分析
bit1129
Stream
以如下代码为例(SocketInputDStream):
Spark Streaming从Socket读取数据的代码是在SocketReceiver的receive方法中,撇开异常情况不谈(Receiver有重连机制,restart方法,默认情况下在Receiver挂了之后,间隔两秒钟重新建立Socket连接),读取到的数据通过调用store(textRead)方法进行存储。数据
spark master web ui 端口8080被占用解决方法
daizj
8080 端口占用 spark master web ui
spark master web ui 默认端口为8080,当系统有其它程序也在使用该接口时,启动master时也不会报错,spark自己会改用其它端口,自动端口号加1,但为了可以控制到指定的端口,我们可以自行设置,修改方法:
1、cd SPARK_HOME/sbin
2、vi start-master.sh
3、定位到下面部分
oracle_执行计划_谓词信息和数据获取
周凡杨
oracle 执行计划
oracle_执行计划_谓词信息和数据获取(上)
一:简要说明
在查看执行计划的信息中,经常会看到两个谓词filter和access,它们的区别是什么,理解了这两个词对我们解读Oracle的执行计划信息会有所帮助。
简单说,执行计划如果显示是access,就表示这个谓词条件的值将会影响数据的访问路径(表还是索引),而filter表示谓词条件的值并不会影响数据访问路径,只起到
spring中datasource配置
g21121
dataSource
datasource配置有很多种,我介绍的一种是采用c3p0的,它的百科地址是:
http://baike.baidu.com/view/920062.htm
<!-- spring加载资源文件 -->
<bean name="propertiesConfig"
class="org.springframework.b
web报表工具FineReport使用中遇到的常见报错及解决办法(三)
老A不折腾
finereport FAQ 报表软件
这里写点抛砖引玉,希望大家能把自己整理的问题及解决方法晾出来,Mark一下,利人利己。
出现问题先搜一下文档上有没有,再看看度娘有没有,再看看论坛有没有。有报错要看日志。下面简单罗列下常见的问题,大多文档上都有提到的。
1、repeated column width is largerthan paper width:
这个看这段话应该是很好理解的。比如做的模板页面宽度只能放
mysql 用户管理
墙头上一根草
linux mysql user
1.新建用户 //登录MYSQL@>mysql -u root -p@>密码//创建用户mysql> insert into mysql.user(Host,User,Password) values(‘localhost’,'jeecn’,password(‘jeecn’));//刷新系统权限表mysql>flush privileges;这样就创建了一个名为:
关于使用Spring导致c3p0数据库死锁问题
aijuans
spring Spring 入门 Spring 实例 Spring3 Spring 教程
这个问题我实在是为整个 springsource 的员工蒙羞
如果大家使用 spring 控制事务,使用 Open Session In View 模式,
com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.
百度词库联想
annan211
百度
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>RunJS</title&g
int数据与byte之间的相互转换实现代码
百合不是茶
位移 int转byte byte转int 基本数据类型的实现
在BMP文件和文件压缩时需要用到的int与byte转换,现将理解的贴出来;
主要是要理解;位移等概念 http://baihe747.iteye.com/blog/2078029
int转byte;
byte转int;
/**
* 字节转成int,int转成字节
* @author Administrator
*
简单模拟实现数据库连接池
bijian1013
java thread java多线程 简单模拟实现数据库连接池
简单模拟实现数据库连接池
实例1:
package com.bijian.thread;
public class DB {
//private static final int MAX_COUNT = 10;
private static final DB instance = new DB();
private int count = 0;
private i
一种基于Weblogic容器的鉴权设计
bijian1013
java weblogic
服务器对请求的鉴权可以在请求头中加Authorization之类的key,将用户名、密码保存到此key对应的value中,当然对于用户名、密码这种高机密的信息,应该对其进行加砂加密等,最简单的方法如下:
String vuser_id = "weblogic";
String vuse
【RPC框架Hessian二】Hessian 对象序列化和反序列化
bit1129
hessian
任何一个对象从一个JVM传输到另一个JVM,都要经过序列化为二进制数据(或者字符串等其他格式,比如JSON),然后在反序列化为Java对象,这最后都是通过二进制的数据在不同的JVM之间传输(一般是通过Socket和二进制的数据传输),本文定义一个比较符合工作中。
1. 定义三个POJO
Person类
package com.tom.hes
【Hadoop十四】Hadoop提供的脚本的功能
bit1129
hadoop
1. hadoop-daemon.sh
1.1 启动HDFS
./hadoop-daemon.sh start namenode
./hadoop-daemon.sh start datanode
通过这种逐步启动的方式,比start-all.sh方式少了一个SecondaryNameNode进程,这不影响Hadoop的使用,其实在 Hadoop2.0中,SecondaryNa
中国互联网走在“灰度”上
ronin47
管理 灰度
中国互联网走在“灰度”上(转)
文/孕峰
第一次听说灰度这个词,是任正非说新型管理者所需要的素质。第二次听说是来自马化腾。似乎其他人包括马云也用不同的语言说过类似的意思。
灰度这个词所包含的意义和视野是广远的。要理解这个词,可能同样要用“灰度”的心态。灰度的反面,是规规矩矩,清清楚楚,泾渭分明,严谨条理,是决不妥协,不转弯,认死理。黑白分明不是灰度,像彩虹那样
java-51-输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
bylijinnan
java
public class PrintMatrixClockwisely {
/**
* Q51.输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
例如:如果输入如下矩阵:
1 2 3 4
5 6 7 8
9
mongoDB 用户管理
开窍的石头
mongoDB用户管理
1:添加用户
第一次设置用户需要进入admin数据库下设置超级用户(use admin)
db.addUsr({user:'useName',pwd:'111111',roles:[readWrite,dbAdmin]});
第一个参数用户的名字
第二个参数
[游戏与生活]玩暗黑破坏神3的一些问题
comsci
生活
暗黑破坏神3是有史以来最让人激动的游戏。。。。但是有几个问题需要我们注意
玩这个游戏的时间,每天不要超过一个小时,且每次玩游戏最好在白天
结束游戏之后,最好在太阳下面来晒一下身上的暗黑气息,让自己恢复人的生气
&nb
java 二维数组如何存入数据库
cuiyadll
java
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace WindowsFormsApplication1
{
本地事务和全局事务Local Transaction and Global Transaction(JTA)
darrenzhu
java spring local global transaction
Configuring Spring and JTA without full Java EE
http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/
Spring doc -Transaction Management
http://docs.spring.io/spri
Linux命令之alias - 设置命令的别名,让 Linux 命令更简练
dcj3sjt126com
linux alias
用途说明
设置命令的别名。在linux系统中如果命令太长又不符合用户的习惯,那么我们可以为它指定一个别名。虽然可以为命令建立“链接”解决长文件名的问 题,但对于带命令行参数的命令,链接就无能为力了。而指定别名则可以解决此类所有问题【1】。常用别名来简化ssh登录【见示例三】,使长命令变短,使常 用的长命令行变短,强制执行命令时询问等。
常用参数
格式:alias
格式:ali
yii2 restful web服务[格式响应]
dcj3sjt126com
PHP yii2
响应格式
当处理一个 RESTful API 请求时, 一个应用程序通常需要如下步骤 来处理响应格式:
确定可能影响响应格式的各种因素, 例如媒介类型, 语言, 版本, 等等。 这个过程也被称为 content negotiation。
资源对象转换为数组, 如在 Resources 部分中所描述的。 通过 [[yii\rest\Serializer]]
MongoDB索引调优(2)——[十]
eksliang
mongodb MongoDB索引优化
转载请出自出处:http://eksliang.iteye.com/blog/2178555 一、概述
上一篇文档中也说明了,MongoDB的索引几乎与关系型数据库的索引一模一样,优化关系型数据库的技巧通用适合MongoDB,所有这里只讲MongoDB需要注意的地方 二、索引内嵌文档
可以在嵌套文档的键上建立索引,方式与正常
当滑动到顶部和底部时,实现Item的分离效果的ListView
gundumw100
android
拉动ListView,Item之间的间距会变大,释放后恢复原样;
package cn.tangdada.tangbang.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import andr
程序员用HTML5制作的爱心树表白动画
ini
JavaScript jquery Web html5 css
体验效果:http://keleyi.com/keleyi/phtml/html5/31.htmHTML代码如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8" >
<ti
预装windows 8 系统GPT模式的ThinkPad T440改装64位 windows 7旗舰版
kakajw
ThinkPad 预装 改装 windows 7 windows 8
该教程具有普遍参考性,特别适用于联想的机器,其他品牌机器的处理过程也大同小异。
该教程是个人多次尝试和总结的结果,实用性强,推荐给需要的人!
缘由
小弟最近入手笔记本ThinkPad T440,但是特别不能习惯笔记本出厂预装的Windows 8系统,而且厂商自作聪明地预装了一堆没用的应用软件,消耗不少的系统资源(本本的内存为4G,系统启动完成时,物理内存占用比
Nginx学习笔记
mcj8089
nginx
一、安装nginx 1、在nginx官方网站下载一个包,下载地址是:
http://nginx.org/download/nginx-1.4.2.tar.gz
2、WinSCP(ftp上传工
mongodb 聚合查询每天论坛链接点击次数
qiaolevip
每天进步一点点 学习永无止境 mongodb 纵观千象
/* 18 */
{
"_id" : ObjectId("5596414cbe4d73a327e50274"),
"msgType" : "text",
"sendTime" : ISODate("2015-07-03T08:01:16.000Z"
java术语(PO/POJO/VO/BO/DAO/DTO)
Luob.
DAO POJO DTO po VO BO
PO(persistant object) 持久对象
在o/r 映射的时候出现的概念,如果没有o/r映射,就没有这个概念存在了.通常对应数据模型(数据库),本身还有部分业务逻辑的处理.可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何对数据库的操作.
VO(value object) 值对象
通
算法复杂度
Wuaner
Algorithm
Time Complexity & Big-O:
http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o
http://bigocheatsheet.com/
http://www.sitepoint.com/time-complexity-algorithms/