Nancy总结(二)记一次Nancy 框架中遇到的坑

记一次Nancy 框架中遇到的坑

   前几天,公司一个项目运行很久的Nancy框架的网站,遇到了一个很诡异的问题。Session 对象跳转到另外一个页面的时候,session对象被清空了,导致用户登录不上。搞了两天,终于解决了。于是把它记录下来,以避免其他人也碰到这种情况。

  起因

  公司一个Nancy 框架 开发的web网站,以前一直都是好的,nancy 框架也用在了很多项目里面,基本上已经很成熟很稳定了,但是在前几天发布某个web网站的时候,竟然出现部分用户登录不上的情况。刚开始以为是人员的权限有问题,于是检查各个人员的权限。但是发现权限设置没问题,而且同一个角色下的两个人,竟然还会出现一个用户能登陆,而另一个却不能登陆的诡异情况。

 

  调查

    在确认不是系统权限设置的问题之后,开始debug 跟踪调试。发现本来已经登陆成功,存储用户登陆信息的session对象,在跳转到index 页面之后,session 对象竟然不清空了,这是怎么回事呢,可是也不是所有的用户的登陆session都会被清空,而是部分人的session对象被清空了,而且登陆功能,在前期一直都是正常的,没出现过这种情况。

  1. 首先怀疑session存储的对象,最近是不是有变动,询问后,发现,User 对象最近确实是增加了一个字段,但是增加一个字段,怎么会影响到session的存储呢,

  2. 把新加的字段去掉,原先不能登陆的用户,竟然能够可以登陆成功,但是其他的一些用户,还是不能登陆,于是开始比较能登陆的用户和不能登陆的用户的数据有什么不同。有可能还是数据的原因,对比之后发现用户数据基本没什么问题,但是普遍的是能登陆上的用户的信息都比不能登陆上的用户的信息要少。

  3. 于是基本可以断定是由于session 存储的用户数据的大小导致的。可是,Nancy 框架下的session 会对 存储数据的大小有限制呢。

 

  解决

  既然知道问题出在哪,于是去jabbr Nancy聊天室问框架的作者。老外表示:Nancysession机制, 是基于cookie 的,客户端和服务器交互的cookie 大小限制在4k 以下,超过4k 就会获取不到。

  但是经过我们的反复测试,确定限制是在2k,而不是4k,我去,坑啊。但是不管是4k还是2k 确实是有这个限制存在。 

  于是问他这个能否设置大一点。老外答复说:大小不能设置,只能修改存存储对象的大小,因为他们在设计之初的时候,session 就不是用来存用户的全部信息的。而是只存用户主要信息或是用户的唯一ID ,到用到用户的信息的时候,再去数据库里面读取。

  看来只能减少用户信息的大小了。于是去掉了Session 里面的User 对象de 一些没有用的字段。果然所有的用户都能进了。 折腾了2天的问题,终于解决。

分享一个控制JS 浏览器缓存的解决办法。

    JS 缓存的问题一直都是我们又爱又恨的东西。也是我们比较头痛的问题,

         一方面为了提高网站响应速度,减少服务器的负担,和节省带宽,将需要将静态资源缓存在客户端,

         但是另一方面,当js 文件有改动的时候,如何快速的将客户端缓存的js文件都失效,这是非常头痛的问题。

         以至于每次客户反馈问题的时候,我们第一个解决办法都是清理浏览器缓存。

 

         那么如何解决呢。

 

         1. 直接禁止全部的静态文件缓存

                   在html 头部加上如下代码:

                  

                  

                  

 

         这样所有的js 文件都不会被缓存。这显然是不可取的。

        

         2.加版本号,在每个js的后面,都加上js 的版本号,

        

        

         当某个js文件有变动时,则修改该js文件的版本号。这样就能解决js 没有更新时,能够缓存js文件,有变动的时,也能更新到最新的js的问题。

        

         但是每次js 有变动时,所有引用到改js的地方都得改一遍,这太麻烦了吧。

        

         有办法:

         1.创建公共js文件,将所有需要控制的js文件加入到JSHash 里面

         //// js files map 本文件可独立运行,无需依赖于其他文件

         var strSite = window.location.protocol + “//” + window.location.host + “/”; //// 网站主机头

        

         var JSHash = { 

                   test: { url: strSite + “test.js”,type:”javascript”, version: “v0001” },

         }

        

         function loadJS(keys) {

                   if (keys) {

                            for (var i = 0; i < keys.length; i++) {

                                     var jsnode = JSHash[keys[i]];

                                     if(jsnode.type=”javascript”)

                                     {

                                               document.writeln(““);

                                     }

                                     else

                                     {

                                               document.writeln(““);

                                     }

                            }

                   }

         }

        

         2. 在相关页面引用js 的方改为:loadJS([“test”]);  

        

         这样每一次更新的时候,只需要调整相关JS的版本号即可。

        

        

 

说一说浏览器缓存

  缓存的问题一直都是我们比较头痛的问题,为了提高网站响应速度,减少服务器的负担,和节省带宽,将需要将静态资源缓存在客户端,

但是有些时候,当这些文件有更新的时候,我们又希望这些缓存能够尽快失效。所以怎么很好的利用缓存功能,而又不影响我们的正常更新。
了解这些缓存机制,就非常有必要。

  浏览器通过URL地址访问一个网页时,浏览器会自动缓存用户访问过网站的网页,当用户下一次在访问这个页面的时候,浏览器就会跟自己本地缓存的页面进行比较
如果网页没有更新的话,浏览器就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页。

  HTTP 缓存相关的几个重要的Header

  Cache-Control

  Cache-Control 这是HTTP缓存最重要的头部字段,用于指定所有缓存机制在整个请求 / 响应 中必须服从的命令。
  cache-control 的定义是:Cache-Control = “Cache-Control”

  public 所有内容都将被缓存
  private 内容只缓存到私有缓存中
  no-cache 所有内容都不会被缓存
  no-store 所有内容都不会被缓存到缓存或 Internet 临时文件中
  must-revalidation/proxy-revalidation 如果缓存的内容失效,请求必须发送到服务器 / 代理以进行重新验证
  max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效 , 这个选项只在 HTTP 1.1 可用 , 并如果和 Last-Modified 一起使用时 , 优先级较高

  Cache-Control 是关于浏览器缓存的最重要的设置,因为它覆盖其他设置,比如 Expires 和 Last-Modified 。另外,由于浏览器的行为基本相同,这个属性是处理跨浏览器缓存问题的最有效的方法。

  Expires
  Expires 头部字段提供一个日期和时间,响应在该日期和时间之后被认为缓存失效。失效的缓存条目通常不会被浏览器返回。
  Expires 的定义是 “Expires: Sun, 08 Nov 2009 03:37:26 GMT”。如果查看内容时的日期在给定的日期之前,则认为该内容没有失效并从缓存中提取出来。反之,则认为该内容失效,缓存将采取一些措施。
  注意:cache-control max-age 和 s-maxage 将覆盖 Expires 头部。

  Last-Modified/E-Tag
  Last-Modified 实体头部字段值通常用作一个缓存验证器。简单来说,在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,
内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:Last-Modified: Fri, 12 May 2006 18:53:33 GMT ,当第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:如果服务器端的资源没有变化,则返回 HTTP 304 (Not Changed.)状态码。而不是响应的文件。

  ETag 是根据web资源生成的一段hash字符串。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,当资源发送改变时,ETag也随之发生变化
以下是服务器端返回的格式:
  ETag: “50b1c1d4f775c61:df3”
  客户端的查询更新格式是这样的:
  If-None-Match: W/”50b1c1d4f775c61:df3″
  如果ETag没改变,则返回状态304,这也和Last-Modified一样。

 

tomcat 无法加载js和css 等静态文件的问题

 

  前段时间做了个网站,在本地tomcat测试都没有问题,但是部署到阿里云上之后,系统样式全没了。jsp等动态页面访问正常。

  打开浏览器监控发现所有的css 和js 文件返回都是404 。直接访问单个的css 文件也同样是404。以为是路径错了,于是一一对了一遍各个文件的路径和服务器上 tomcat路径方面的设置

  发现路径没有问题。在网站更目录创建一个css文件和html文件均不能访问。确认不是网站路径的问题。

  然后怀疑是tomcat 和 Apache 冲突了,或者可能是Apache 的设置不对。因为阿里云是默认的镜像,里面已经装了Apache和tomcat。也没有做什么设置。

  于是直接把Apache 服务停止。但是还是没有用,依然无法访问css 和html 页面。

  然后怀疑是不是服务器js 和css 这两个文件的目录权限有问题,查看了这两个文件夹的权限。没有问题,

  而且在jsp文件能访问的目录,直接创建一个js 文件,同样不能访问。于是权限的怀疑被排除。

  想了半天还是不知道到底是哪配置不对。然后突然想到所有的请求都是nginx 分发的。 是不是nginx 的配置不对。但是一想nginx 配置不对的话,那网站都不能访问啊。为什么jsp 页面能访问而静态文件不行。 带着这个疑问,去查看下nginx的配置,打开nginx conf文件夹中的nginx.conf,果然发现了nginx配置可疑的地方。

  server
  {
    listen 80;
    server_name localhost;
    index index.html index.htm index.jsp;
    root /var/www/web/ROOT;

    location ~ .*.jsp$
    {
      index index.jsp;
      proxy_pass http://localhost:8080;
    }

    locattion *.jsp$ 的意思就是所有jsp的页面均交由tomcat处理。
    root 就是网站的资源存放路径。

    终于清楚了,服务器把所有的请求都是由nginx 转发。nginx 会把 jsp 的请求转给tomcat 来处理,

    至于静态资源的请求 nginx 直接就处理了,直接把资源文件返回给客户端,无需tomcat 处理。

    于是修改root 的设置, 将地址指向实际的网站资源文件的地址。 回到页面重新测试,果然好了。

    刚开始不知道原因,各种测试,各种改代码,服务器相关的设置都改了一遍。知道真相之后,其实要解决非常简单。

 

 

关于开发和测试沟通的一些问题

1.分工测试,
2.不是每次都要测试全部功能,主要测试那些常用的重点功能,
3.尽量不要用电话,qq,也不要发现问题就找开发人员,要用邮件报告发给项目负责人,由项目负责人统一判断,安排,
4.不是随时报告,而是下班的时候统一发给各个测试负责人汇总自己组内的测试,合并重复的问题,提交给项目负责人,
5.每个测试小组每天的测试报告要连在一起,要有连贯性,
6.每个问题要标好功能模块,要有测试人,测试版本号,测试时间,截图,输入数据等。
7.不要把需求和问题混在一起,
8.测试报告中各种描述要清楚,明确。不要出现不好用,无效,等描述,

活着

  活着,在我们中国的语言里充满了力量,它的力量不是来自于叫喊,也不是来自于进攻,

  而是忍受,去忍受生命赋予我们的责任,去忍受现实给予我们的幸福和苦难、无聊和平庸。

  所以在那些悲伤的情节之间,福贵在死亡的伴随下活着,述说苦难的时候,眼睛里流出了奇妙的神色,分不清是悲伤,还是欣慰。

  正如你终于会明白,无论现时我们经历的是措手不及的幸福喜悦,抑或是无可告人的艰辛苦难,

  只要继续活着,它们中的大多数细节和感受都将被我们和时间一一遗忘,只留下苍白的结果。那个结果对现时的我们毫发无伤。

关于结婚

  荷西问三毛:你想嫁个什么样的人?三毛说:看的顺眼的,千万富翁也嫁。看的不顺眼的,亿万富翁也嫁。荷西就说:那说来说去你还是想嫁个有钱的。三毛看了荷西一眼说:也有例外的时候。那你要是嫁给我呢”荷西问道。三毛叹了口气说:要是你的话那只要够吃饭的钱就够了“那你吃得多吗?”荷西问道“不多不多,以后还可以少吃一点。”三毛小心的说道。

robots.txt的介绍和写作

  目前很多网站管理者似乎对robots.txt并没有引起多大重视,甚至不知道这么一个文件的作用。
本来应该保密的信息被爬虫抓取了,公布在公网上,本应该发布到公网的信息却迟迟不被搜索引擎收录。所以下面这篇文章,就来介绍robots.txt的作用和写作

robots.txt基本介绍
  robots 是一个纯文本文件,是用来告诉搜索引擎:当前这个网站上哪些部分可以被访问、哪些不可以,robots文件是存放在网站根目录下的一个纯文本文件。当搜索引擎访问一个网站时,它首先会检查该网站根目录下是否存在robots文件。robots文件必须放置在一个网站的根目录下,而且文件名必须全部小写。
我们做的网站肯定希望被收录,因为网站流量的一部分或者是大部分都是来自搜索,所以对网站来说是很重要的。问题是:我们有的网站内容不希望杯搜索到,那么怎么办呢?在这种情况下,我们就有必要会用到robots文件,来与搜索引擎沟通。所有的搜索引擎蜘蛛自动在网站根目录中寻找这个文件,所以你只需创建它并上传,然后等待蜘蛛来阅读。
  另外,robots.txt必须放置在一个站点的根目录下,而且文件名必须全部小写。当需要完全屏蔽文件时,需要配合meta的robots属性。

robots.txt写作语法
首先,我们来看一个robots.txt范例:

# All robots will spider the domain
User-agent: *
Disallow:

以上文本表达的意思是允许所有的搜索机器人访问当前站点下的所有文件。

具体语法分析:其中#后面文字为说明信息;User-agent:后面为搜索机器人的名称,后面如果是*,则泛指所有的搜索机器人;Disallow:后面为不允许访问的文件目录。

下面,我将列举一些robots.txt的具体用法:

1.允许所有的robot访问
User-agent: *
Disallow:
或者也可以建一个空文件 “/robots.txt” file

2.禁止所有搜索引擎访问网站的任何部分
User-agent: *
Disallow: /

3.只允许某个搜索引擎的访问,我用e来代替
User-agent: e
Disallow:
在Disallow:后面不加任何东西,意思是仅允许e访问该网站。

4.禁止所有搜索引擎访问网站的几个部分(下例中的01、02、03目录)
User-agent: *
Disallow: /01/
Disallow: /02/
Disallow: /03/

5.禁止某个搜索引擎的访问(下例中的BadBot)
User-agent: BadBot
Disallow: /

6.使用”$”限制访问url
User-agent: *
Allow: .htm$
Disallow: /
意思是仅允许访问以”.htm”为后缀的URL

7禁止访问网站中所有的动态页面
User-agent: *
Disallow: /*?*

8.禁止搜索引擎F抓取网站上所有图片
User-agent: F
Disallow: .jpg$
Disallow: .jpeg$
Disallow: .gif$
Disallow: .png$
Disallow: .bmp$
意思是只允许引擎抓取网页,禁止抓取任何图片(严格来说,是禁止抓取jpg、jpeg、gif、png、bmp格式的图片。)

9.只允许搜索引擎E抓取网页和.gif格式图片
User-agent: E
Allow: .gif$
Disallow: .jpg$
Disallow: .jpeg$
Disallow: .png$
Disallow: .bmp$
意思是只允许抓取网页和gif格式图片,不允许抓取其他格式图片

10.Sitemap:sitemap是给搜索引擎爬虫指路的地图,引导搜索引擎爬虫去抓取相应的地址
sitemap在robots文件的写法如下:
Sitemap:http://***.com/sitemap.txt
切记S是大写的!

 

注意事项
1.网站应该要有一个robot.txt文件,
2.绝大多数的搜索引擎机器人都遵守robots文件的规则,
3.文件名是小写字母。
4.要提醒大家的是:robots.txt文件一定要写对,如果不太会写,还是要先了解再写,以免给网站的收录带来麻烦。

 

asp.net 中的app_offline.htm的使用

前段时间,系统升级,由于系统更新发布时间较长,所以必须停掉站点进行更新。导致很多用户都来反馈系统无法访问,还认为站点被黑掉了。

所以经过那件事我们也在思考,如何做到不停机,进行热部署。
单机环境下(双机或是分布式系统不用考虑这个问题),app_offline.htm是个不错的选择,

当asp.net看到应用程序中app_offline.htm文件时,它会关闭应用程序的app-domain,然后将请求发给app_offline的内容。

所以,在维护,升级的时候,就不必停止你的WEB应用程序,而是一个友好的方式提示给用户,本网站正在更新的提示,这样体验会更友好。

 

1. 创建一个app_offline.htm的HTM页面文件,



"Content-Type"
content="text/html; charset=gb2312">
站点更新中



站点更新中

站点更新中,请稍后访问。

 

2. 将app_offline.htm放在你的网站根目录下。这样,任何外部的请求的话,都会马上被转移到该页面了。

需要注意的是:
(1)app_offline.htm 不能小于 512 字节。
(2)IIS 站点和进程池不需要停止。
(3)只有对.aspx文件的请求才自动转到app_offline.htm文件;如果请求的是.htm, .asp等文件,则不会转到app_offline.htm