A10 有没有能做热点统计

 
1 Varnish 分布式 HA  (目前没有HA)
2 Varnish 热点监控     (建议热点需要外部插件统计,API的话目前并木有发现,但是他自带一个伪热点功能)
如果用外部插件统计热点。  热点的读写Varnish 比较有难度。 Varnish是VCL语言编写。 而配置文件使用C语言方法。
 
Varnish的优势
 
Varnih 的对比Squid可靠性高,Squid服务器发生故障的几率要高于Varnish,因为使用Squid要经常重启;
 
Varnish 采用了“Visual Page Cache”技术,缓存数据内存读,squid是从硬盘读取
 
Varnish 支持多并发连接,因为Varnish的TCP连接释放要比Squid快,因而在高并发连接情况下可以支持更多TCP连接;
 
Varnish 可以通过管理端口,使用正则表达式批量的清除部分缓存,而Squid是做不到的;
 
squid 属于是单进程使用单核CPU,但 Varnish 是通过 fork 形式打开多进程来做处理,所以可以合理的使用所有核来处理相应的请求;
 
Varnish的劣势
 
varnish进程一旦Hang、Crash或者重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力;
 
在varnish使用中如果单个url的请求通过HA/F5等负载均衡,则每次请求落在不同的varnish服务器中,造成请求都会被穿透到后端;而且同样的请求在多台服务器上缓存,也会造成varnish的缓存的资源浪费,造成性能下降;
 
 
Varnish劣势的解决方案
 

针对劣势一:在访问量很大  

的情况下推荐使用varnish的内存缓存方式启动,而且后面需要跟多台squid服务器。主要为了防止前面的varnish服 务、服务器被重启的情况下,大量请求穿透varnish,这样squid可以就担当第二层CACHE,而且也弥补了varnish缓存在内存中重启都会释 放的问题;
 

针对劣势二:可以在负载均衡上做url哈希,让单个url请求固定请求到一台varnish服务器上;  

 
可以数据存硬盘上。  热点数据车存储在 SSD 硬盘。
 
可行性分析整理: 
   两台 Varnish 机器做HA(两台机器分别安装Varnish且不同步)(伪同步 HA 可保证) 
   缺点:将会造成冗余存储。 两台机器缓存较多为一致。 
   优点:如果出现一台机器宕机。可以避免大量请求压死后端、且伪同步可以节省部分内存空间,过滤掉量小的请求。并集才会存储在内存中。
 
 热点分析问题:
   如果要做热点分析,Varnish 内部是不支持的, 需要外部插件做。且需要C方便的哥们志愿一下写内存插入功能。
   建议:varnish 中没有热点分析。 但是有命中数统计。 可以设置超过一定命中数后 设置TTL的值。  还可以设置 varnish 缓存此图片的时间延长。

 
Varnish 是 VCL语言编写的
解析方式是讲配置文件方法转成 C 编译执行。
 
 
 
 
vcl_fetch 在一个文件成功从后台获取后被调用,通常他的任务就是改变 response headers,触发 ESI 进程,在请求失败的时候轮询其他服务器。{
actions
主要有以下动作
pass  \\请求转发后端服务器不缓存。
lookup \\当请求在 vcl_recv 中被 lookup 后,varnish 将从缓存中提取数据,如果缓存中没有数据,将被设置为 pass,不能在 vcl_fetch 中设置 lookup。
pipe \\pipe 和 pass 相似,都要访问后端服务器,不过当进入 pipe 模式后,在此连接未关闭前,后续的所有请求都发到后端服务器(这句是我自己理解后简化的,有能力的朋友可以看看官方文档,给我提修改建议) 。
deliver \\请求的目标被缓存,然后发送给客户端
esi \\ESI-process the fetched document(我理解的就是 vcl 中包换一段 html
}
 
Statistics (统计 varnish  相关数据)
现在您的 varnish 已经正常运行,我们来看一下 varnish 在做什么,这里有些工具可
以帮助您做到。
Varnishtop
Varnishtop工具读取共享内存的日志, 然后连续不断的显示和更新大部分普通日志。
适当的过滤使用 –I,-i,-X 和-x 选项,它可以按照您的要求显示请求的内容,客
户端,浏览器等其他日志里的信息。
varnishtop -i rxurl \\您可以看到客户端请求的 url 次数。
Varnishtop -i txurl \\您可以看到请求后端服务器的 url 次数。
Varnishtop -i Rxheader –I Accept-Encoding \\可以看见接收到的头信息中有有多少次
包含 Accept-Encoding。
Varnishstat
Varnish 有很多计数器,我们计数丢失率,命中率,存储信息,创建线程,删除对
象等,几乎所有的操作。Varnishstat 将存储这些数值,在优化 varnish 的时候使用这个命令。
有一个程序可以定期轮询 varnishstat 的数据并生成好看的图表。这个项目叫做
Munin。 Munin 可以在 http://munin-monitoring.org/找到。 在 varnish 的源码中有 munin 插件。
 
——————————————————————————————————————————————————————————————————————————————
 
 
                                                                                                        技术笔记
 
        varnish 有一个概念叫做“后端服务器”或者叫“原点服务器” ,一个后端服务器将提供 varnish 加速的内容。我们的第一个任务就是告诉 varnish 在哪里可以找到他要的内容。如果您是源码安装的配置文件可能在
varnish(3.0.0)/etc/default.vcl 配置详解
/etc/varnish/default.vcl.
配置文件的最顶端如下:
backend default {
  .host = "127.0.0.1";
  .port = "80";
}
 
现在,这块配置定义了一个 varnish 默认访问的后端服务器,当 varnish 需要从后端
服务器获取内容的时候,它就会访问自己(127.0.0.1)的 80 端口。
Varnish 可以定义多个后端服务器而且您可以通过定义多个后端服务器达到负载均
 
backend server2 {
.host = "server2.example.com";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
这些新的就是探针,varnish 将检查通过探针检查每个后端服务器是否健康:
url \\哪个 url 需要 varnish 请求。
Interval \\检查的间隔时间
Timeout \\等待多长时间探针超时
Window \\varnish 将维持 5 个 sliding window 的结果
Threshold  \\至少有 3 次.windows 检查是成功的,就宣告 backends 健康
 
 
 
 
衡的目的。
命令 示例: 
varnishd -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:8080
 
varnishd -f /usr/local/etc/varnish/default.vcl
        指定 Varnish 使用哪个配置文件 。
-s malloc,1G
        –s 选项用来确定 varnish 使用的存储类型和存储容量,我使用的是 malloc 类型(malloc 是一个 C 函数,用于分配内存空间)  1G 定义多少内存被 malloced,1G =1gigabyte
-T 127.0.0.1:2000
        Varnish 有一个基于文本的管理接口,启动它的话可以在不停止 varnish 的情况下来管理 varnish。您可以指定管理软件监听哪个接口。当然您不能让全世界的人都能访问您的varnish 管理接口, 因为他们可以很轻松的通过访问 varnish 管理接口来获得您的 root 访问权限。我推荐只让它监听本机端口。如果您的系统里有您不完全信任的用户,您可以通过防火墙规则来限制他访问 varnish 的管理端口
-a 0.0.0.0:8080
        这一句的意思是制定 varnish 监听所有 IP 发给 8080 端口的 http 请求,如果在生产环境下,您应该让 varnish 监听 80,这也是默认的。
 
 
 
Varnish 支持将数据写硬盘上
 
 
VCL 支持以下运算符,请阅读下面的例子:
=  \\赋值运算符
== \\对比
~  \\匹配,在 ACL 中和正则表达式中都可以用
! \\否定
&& \\逻辑与
||  \\逻辑或
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Varnish配置文件详解

既然Varnish需要在多台服务器上缓存数据,就需要Varnish映射所有的URL到一台单独的主机。


  1. backend webserver {
  2. .host = "127.0.0.1";
  3. .port = "80";
  4. .connect_timeout = 4s;
  5. .first_byte_timeout = 5s;
  6. .between_bytes_timeout = 20s;
  7. }

该块配置用于定义一台Varnish默认访问的后端服务器,当Varnish需要从后端服务器获取数据时,就会访问自己的80端口。

当然Varnish也可以定义多台后端服务器实现负载均衡的目的。

.connect_timeout定义的是等待连接后端的时间

.first_byte_timeout定义的是等待从backend传输过来的第一个字节的时间

.between_bytes_timeout 定义的是两个字节的间隔时间

当然还可以增加一个backend,用于访问本机的8090端口,假设通过该端口提供图片服务。


  1. backend img {
  2. .host = "127.0.0.1";
  3. .port = "8090";
  4. }

当匹配img的URL时,需把请求发送到上面定义的backend img,其他的请求发送到backend webserver。


  1. sub vcl_recv {
  2. if (req.url ~ "^/img/") {
  3. set req.backend = img;
  4. } else {
  5. set req.backend = webserver.
  6. }
  7. }

Varnish不仅仅可以定义多个backend,还可以把多个backend合成一个组,使用循环的方式把请求分配给组中的backends。并且Varnish会根据健康检查情况来判断后端服务器是否正常提供服务。

Varnish使用区域语言VCL来管理定义Varnish的存取策略。VCL语法简单,跟Perl比较相似,可以使用多种运算符如"="、"=="、"!,&&,!!"等形式;也可以使用正则表达式来进行匹配,还可以使用"set"来指定变量。当执行VCL时,Varnish会先把VCL转换成二进制代码。

有一点要注意,"\"字符在VCL里没有什么特别的含义,这点和其他语言不同。另外,VCL只是配置语言,并不是真正的编程语言,所以没有循环和自定义变量。

为了可以更好地对Varnish进行配置调整,需要了解Varnish的配置语法,也就是VCL语言。下面对VCL常用的一些函数和变量进行介绍。

(1)vcl_recv模块

用于接收和处理请求。当请求成功被调用后,Varnish通过判断请求的数据来决定如何处理请求。此模块一般以如下几个关键字结束。

pass:表示进入pass模式,把请求交给vcl_pass模块处理。

pipe:表示进入pipe模式,把请求交给vcl_pipe模块处理。

error code [reason]:表示把错误标识返回给客户端,并放弃处理该请求。错误标识包括200、405等。"reason"是对错误的提示信息。

(2)vcl_pipe模块

此模块在请求进入pipe模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,也就是在当前连接未关闭时,服务器将不变的内容返回给客户端,直到该连接被关闭。

(3)vcl_pass模块

此模块表示当请求被pass后,用于将请求直接传递至后端应用服务器。后端应用服务器在接收请求后将数据发送给客户端,但不进行任何数据的缓存,在当前连接下每次都返回最新的内容。

(4)lookup

一个请求在vcl_recv中被lookup后,Varnish将在缓存中提取数据。如果缓存中有相应的数据,就把控制权交给vcl_hit模块;如果缓存中没有相应的数据,请求将被设置为pass并将其交给vcl_miss模块。

(5)vcl_hit模块

执行lookup指令后,Varnish在缓存中找到请求的内容后将自动调用该模块。

在此模块中,deliver表示将找到的数据发送给客户端,并把控制权交给vcl_deliver模块。

(6)vcl_miss模块

执行lookup后,Varnish在缓存中没有找到请求的内容时会自动调用该方法。此模块可以用于判断是否需要从后端服务器获取内容。

在此模块中,fetch表示从后端获取请求的数据,并把控制权交给vcl_fetch模块。

(7)vcl_fetch模块

在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。

(8)vcl_deliver模块

当一个没有被缓存的数据交付给客户端的时候被调用。

(9)vcl_timeout 模块

在缓存数据到期前调用此模块。

在此模块中,discard表示从缓存中清除到期数据。

(10)vcl_discard模块

在缓存数据到期后或缓存空间不够时,自动调用该模块。

在此模块中keep表示将数据继续保留在缓存中。


  1. acl purge {
  2. "localhost";
  3. "127.0.0.1";
  4. "18.81.12.10";
  5. }
  6. if (req.request == "PURGE") {
  7. if (!client.ip ~ purge) {
  8. error 405 "Not allowed.";
  9. }
  10. return(lookup);
  11. }

这两个规则定义了允许哪些主机通过HTTP来执行PURG进行缓存删除。如果不是指定的IP,就会出现HTTP 405错误,提示Not allowed错误字样。


  1. if (req.http.host ~ "^(read)?.aaa.com$") {
  2. set req.backend = webserver;
  3. if (req.request != "GET" && req.request != "HEAD") {
  4. return(pipe);
  5. }
  6. else {
  7. return(lookup);
  8. }
  9. }
  10. else {
  11. error 404 " Cache Server";
  12. return(lookup);
  13. }

这段条件判断用于对aaa.com域名进行缓存加速,aaa.com是泛指概念,也就是说所有以aaa.com结尾的域名都进行缓存。而if (req.request != "GET" && req.request != "HEAD") 表示"如果请求的类型不是GET与HEAD",则返回错误码404。


  1. if (req.url ~ "^/images") {
  2. unset req.http.cookie;
  3. }

这条规则的意思是清除服务器上/images目录下的所有缓存,当这个请求在后端服务器生效时,如果访问的URL匹配这个规则,那么头信息中的cookie就会被删除。


  1. if (req.request == "GET" && req.url ~ "\. (png|swf|txt|png|gif|jpg|css|js|htm| html)$") {
  2. unset req.http.cookie;
  3. }
  4. if (req.http.x-forwarded-for) {
  5. set reqreq.http.X-Forwarded-For =
  6. req.http.X-Forwarded-For ", " client.ip; }
  7. else { set req.http.X-Forwarded-For = client.ip; }

因为Squid、Varnish都会把客户端的IP地址放在HTTP_X_FORWARDED_FOR里面传给后端的Web服务器,所以后端的Web程序都要对其进行调用。


  1. if (req.request != "GET" &&
  2. req.request != "HEAD" &&
  3. req.request != "PUT" &&
  4. req.request != "POST" &&
  5. req.request != "TRACE" &&
  6. req.request != "OPTIONS" &&
  7. req.request != "DELETE") {
  8. return (pipe);
  9. }

该if判断表示如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,则进入pipe模式。注意这里的"&&"是与的关系。


  1. if (req.request == "GET" && req.url ~ "\. (png|swf|txt|png|gif|jpg|css|js|htm| html)") {
  2. set beresp.ttl = 180s;
  3. }
  4. else {
  5. set beresp.ttl = 30d;
  6. }
  7. return (deliver);
  8. }

该if判断用于对请求类型是GET,并且请求的URL以png、swf、txt、gif、css、js等结尾时,则进行缓存,缓存时间为180秒。其他缓存为30天。


  1. sub vcl_deliver {
  2. set resp.http.x-hits = obj.hits ;
  3. if (obj.hits > 0) {
  4. set resp.http.X-Cache = "HIT read.easouu.com";
  5. }
  6. else {
  7. set resp.http.X-Cache = "MISS read.easou.com";
  8. }

这个模块定义的是添加一个Header标识,以判断缓存是否命中。


  1. sub vcl_error {
  2. set obj.http.Content-Type = "text/html; charset=utf-8";
  3. synthetic {"
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict// EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-strict.dtd">
  6. <html>
  7. <head>
  8. <title>"} obj.status " " obj.response {"</title>
  9. </head>
  10. <body>
  11. <h1>Error "} obj.status " " obj.response {"</h1>
  12. <p>"} obj.response {"</p>
  13. <h3>Guru Meditation:</h3>
  14. <p>XID: "} req.xid {"</p>
  15. <hr>
  16. <address>
  17. <a href="http://read.easou.com/">read.easou.com</a>
  18. </address>
  19. </body>
  20. </html>
  21. "};
  22. return (deliver);
  23. }

最后这个模块定义了访问错误页面时的返回信息。

现在varnish配置基本完成,可以在8080端口上启动varnish,并进行一些基本的测试。

Varnish缓存的配置

简单的配置文件内容如下:


    1. backend webserver {
    2. .host = "127.0.0.1";
    3. .port = "8090";
    4. .connect_timeout = 4s;
    5. .first_byte_timeout = 5s;
    6. .between_bytes_timeout = 20s;
    7. }
    8. acl purge {
    9. "localhost";
    10. "127.0.0.1";
    11. "18.81.12.10";
    12. }
    13. sub vcl_recv {
    14. if (req.request == "PURGE") {
    15. if (!client.ip ~ purge) {
    16. error 405 "Not allowed.";
    17. }
    18. return(lookup);
    19. }
    20. if (req.http.host ~ "^(read)?.easou.com$") {
    21. set req.backend = webserver;
    22. if (req.request != "GET" && req.request != "HEAD") {
    23. return(pipe);
    24. }
    25. else {
    26. return(lookup);
    27. }
    28. }
    29. else {
    30. error 404 " Cache Server";
    31. return(lookup);
    32. }
    33. if (req.request == "GET" && req.url ~ "\.(png|swf|txt|png|gif|jpg|css|js| htm|html)$") {
    34. unset req.http.cookie;
    35. }
    36. if (req.url ~ "^/images") {
    37. unset req.http.cookie;
    38. }
    39. if (req.http.Cache-Control ~ "(no-cache|max-age=0)") {
    40. purge_url(req.url);
    41. }
    42. return (lookup);
    43. if (req.http.x-forwarded-for) {
    44. set reqreq.http.X-Forwarded-For =
    45. req.http.X-Forwarded-For ", " client.ip; }
    46. else { set req.http.X-Forwarded-For = client.ip; }
    47. if (req.request != "GET" &&
    48. req.request != "HEAD" &&
    49. req.request != "PUT" &&
    50. req.request != "POST" &&
    51. req.request != "TRACE" &&
    52. req.request != "OPTIONS" &&
    53. req.request != "DELETE") {
    54. return (pipe);
    55. }
    56. if (req.request != "GET" && req.request != "HEAD") {
    57. return (pass);
    58. }
    59. if (req.http.Authorization || req.http.Cookie) {
    60. return (pass);
    61. }
    62. }
    63. sub vcl_pipe {
    64. # set req.http.connection = "close";
    65. return (pipe);}
    66. sub vcl_hit {
    67. if (!obj.cacheable) {
    68. return (pass);
    69. }
    70. if (req.request == "PURGE") {
    71. set obj.ttl = 0s;
    72. error 200 "Purged.";
    73. }
    74. return (deliver);
    75. }
    76. sub vcl_miss {
    77. return (fetch);
    78. }
    79. sub vcl_fetch {
    80. if (!beresp.cacheable) {
    81. return (pass);
    82. }
    83. if (beresp.http.Set-Cookie) {
    84. return (pass);
    85. }
    86. if (beresp.http.Pragma ~ "no-cache" ||
    87. beresp.http.Cache-Control ~ "no-cache" ||
    88. beresp.http.Cache-Control ~ "private") {
    89. return (pass);
    90. }
    91. if (req.url ~ "^/cover/") {
    92. set beresp.ttl = 1800s;
    93. }
    94. else {
    95. set beresp.ttl = 30d;
    96. }
    97. return (deliver);
    98. #       if (req.request == "GET" && req.url ~ "\.(png|swf|txt|png|gif|jpg|css|js| htm|html|jsp)") {
    99. #               set beresp.ttl = 180s;
    100. #       }
    101. #       else {
    102. #               set beresp.ttl = 30d;
    103. #       }
    104. #        return (deliver);
    105. }
    106. sub vcl_deliver {
    107. set resp.http.x-hits = obj.hits ;
    108. if (obj.hits > 0) {
    109. set resp.http.X-Cache = "HIT read.easouu.com";
    110. }
    111. else {
    112. set resp.http.X-Cache = "MISS read.easou.com";
    113. }
    114. }
    115. sub vcl_error {
    116. set obj.http.Content-Type = "text/html; charset=utf-8";
    117. synthetic {"
    118. <?xml version="1.0" encoding="utf-8"?>
    119. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-strict.dtd">
    120. <html>
    121. <head>
    122. <title>"} obj.status " " obj.response {"</title>
    123. </head>
    124. <body>
    125. <h1>Error "} obj.status " " obj.response {"</h1>
    126. <p>"} obj.response {"</p>
    127. <h3>Guru Meditation:</h3>
    128. <p>XID: "} req.xid {"</p>
    129. <hr>
    130. <address>
    131. <a href="http://read.easou.com/">read.easou.com</a>
    132. </address>
    133. </body>
    134. </html>
    135. "};
    136. return (deliver);
    137. }

    Varnish 简介

    Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,很多大型的网站都开始尝试使用 varnish 来替换 squid,这些都促进 varnish 迅速发展起来。

    挪威的最大的在线报纸 Verdens Gang(vg.no) 使用 3 台 Varnish 代替了原来的 12 台 Squid,性能比以前更好,这是 Varnish 最成功的应用案例。

     

    回页首

    Varnish 文件缓存的工作流程

    Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。

    接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。

    分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。

    释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。

    整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。

 

Varnish 问题点 与 技术方案 Varnish 优劣分析的更多相关文章

  1. 如何写好B端产品的技术方案?

    B端产品为企业提供协同办公的工具,帮助企业解决某类经营管理问题,核心价值在于为企业增加收入.降本提效.管控风险,企业级SaaS产品也是B端产品中的一类. B端产品有以下特点: ​客户是一个群体:B端产 ...

  2. 分布式锁1 Java常用技术方案

    前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...

  3. unity小地图技术方案总结

    技术方案 一:从顶视图获取实时小地图(优点实现快容易对地图进行放大缩小操作而且地图,缺点是不好对地图做出修改,只能在顶部加个另外的相机层来遮盖) 1.创建Redertexture并改名为smallma ...

  4. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  5. Facebook存储技术方案:找出“暖性BLOB”数据

    Facebook公司已经在其近线存储体系当中彻底弃用RAID与复制机制,转而采用分布式擦除编码以隔离其所谓的“暖性BLOB”. 暖性?BLOB?这都是些什么东西?大家别急,马上为您讲解: BLOB—— ...

  6. 分布式锁1 Java常用技术方案(转)

    转:http://www.cnblogs.com/PurpleDream/p/5559352.html#3450419 前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临 ...

  7. Android基于WIFI实现电脑和手机间数据传输的技术方案研究

    Android手机和电脑间基于wifi进行数据传输,从技术上讲,主要有两种方案: 一种是通过ftp协议实现,Android手机作为数据传输过程中的ftp服务器: 一种是通过http协议实现.Andro ...

  8. Binder Proxy技术方案

    Binder Proxy技术方案 作者 低端码农 时间 2014.08.23 0x0 看到有多朋友尝试通过hook系统进程system_process的ioctl,以企图截获系统的IPC通讯.这个方法 ...

  9. 技术方案:在外部网址调试本地js(基于fiddler)

    1 解决的问题 1)        场景1:生产环境报错 对前台开发来说,业务逻辑都在js中,所以报错90%以上都是js问题. 如果生产环境出现报错,但是测试环境正常.这时修改了代码没有环境验证效果, ...

随机推荐

  1. C语言中的作用域、链接属性与存储属性

    C语言中的作用域.链接属性与存储属性 一.作用域(scope) 代码块作用域 表示{}之间的区域,下例所示,a可以在不同的代码块里面定义. #include<stdio.h> int ma ...

  2. Ajax通过script src特性加载跨域文件 jsonp

    <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Do ...

  3. makefile--回顾基础篇

    前阵子让写makefile,纠结了下,基本忘记差不多了. 1.gcc的编译选项 -c 只是编译不链接,生成目标文件“.o” -S 只是编译不汇编,生成汇编代码 -E 只进行预编译,不做其他处理 -g ...

  4. linux 系统相关命令

    说明:此篇以 Debian ( ubuntu16.04 ) 命令为例 1. tab键默认是不能自动补全命令 apt install bash-completion // 安装完成之后重启系统 2. 虚 ...

  5. mac pro配置php开发环境

    mac pro自带php和apache,所以我们只要配置下就好了 // 启动Apache服务 sudo apachectl start // 重启Apache服务 sudo apachectl res ...

  6. CodeForces 445E DZY Loves Colors

    DZY Loves Colors Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...

  7. Qt之图形(绘制漂亮的圆弧)

    简述 综合前面对二维绘图的介绍,想必我们对一些基本绘图有了深入的了解,下面我们来实现一些漂亮的图形绘制. 简述 圆形 效果 源码 弧形 效果 源码 文本 效果 源码 旋转 效果 源码 圆形 经常地,我 ...

  8. poj_3371

    一道模拟题,写的有点麻烦 #include<iostream> #include<cstring> #include<cstdio> #include<alg ...

  9. [AGC018 B] Sports Festival 解题报告

    题目链接:https://agc018.contest.atcoder.jp/tasks/agc018_b 题目: 题目大意: 有N个人参加M个体育项目,每个人对体育项目的喜爱程度有一个排名,A[i] ...

  10. Looping and dictionaries

    If you use a dictionary in a for statement, it traverses the keys of the dictionary. For example, pr ...