精华内容
下载资源
问答
  • 通过视图(VIEW)的使用,ClearCase提供了一套独立的工作空间管理设施,可以实现动态评估、选择指定用户版本和透明的访问多种配置功能。 版本间的透明访问 ClearCase提供了对版本进行透明访问的功能。通过VOB机制...
    快速、有效的工作空间建立对于提高个人和团队的效益是非常重要的。通过视图(VIEW)的使用,ClearCase提供了一套独立的工作空间管理设施,可以实现动态评估、选择指定用户版本和透明的访问多种配置的功能。 
    
    版本间的透明访问
      ClearCase提供了对版本进行透明访问的功能。通过VOB机制(包含文件或目录的多个版本),ClearCase可以让开发者和应用者以一种标准文件目录树的形式访问VOB。这个特性被成为透明――ClearCase的版本控制系统因而变得可视化。
      透明是一个非常重要的特性,它允许ClearCase在使用系统软件、商业应用和内部工具时进行平滑的工作。比如:象grep,more,ls,cc这种标准UNIX程序,在操作ClearCase版本控制数据时与操作一般的文件系统对象的方式一样。
      通过ClearCase的多版本文件系统可以(MVFS)在虚拟文件系统上实现透明操作。MVFS可中断标准的I/O调用,并且ClearCase的版本选择结构可以细化到从一个元素到另一个元素版本的目标调用。
      对于Windows NT,ClearCase的MVFS一般缺省作为"M:"驱动盘出现,活动视图作为"M:"盘的根目录出现。正常情况下,ClearCase可以为每一个活动视图分配更多的虚拟盘(从"Z:"以后工作―)。把VOB设置成每一个虚拟盘的子目录。这样就可以让开发者使用自己的工具透明的访问被ClearCase控制的数据,甚至是UNIX VOBs和视图。
    通过规则视图选择并显示版本
      ClearCase的视图提供了强大的、独立的工作空间管理(也称作"环境管理"或"沙盒管理")。通过使用动态评估、用户指定版本选择规则,视图可以让开发者对任何元素的任何版本进行透明的、文件级的访问。ClearCase的视图具有灵活性、可调性、有效性并可随时自动更新。
      通过开发者对ClearCase控制的数据和程序的版本进行选择,视图可以对完整的文件系统配置进行动态管理。它也可以访问主机上的其它数据和程序。
      ClearCase支持规范的开发环境,它可以维护公有和私人两种数据存储类型。所有的ClearCase用户可以共享或公开在VOB中存储的数据,它们包括一些常规访问的计划信息。存储在视图中的私有数据一般包含属于开发者个人的文件,如:通过标准工具被检出的文件元素版本,在视图中由ClearCase建立的原始对象,和由视图用户在VOB目录中建立的文件和目录。视图在"虚拟工作空间"存储了这两种数据,开发者每天对其执行检入、检出、编辑原文件操作、建立软件和修复系统等操作。
      在视图中选择的版本可以称为视图配置。视图配置是动态的并可以在任何时候被开发者修改。视图配置在配置规格说明的一系列规章被定义。一般的,视图的配置在通配符和助记符的术语表中被定义,而不是通过指定具体的版本名称。 每个开发者都可以拥有多个视图,并且可以在任何视图中设置过程。此外,不同视图可以看同一路径名下的同一元素的不同版本。比如:一个视图可以浏览某一元素最近的版本;另一视图也可浏览该元素的某一版本,它可能曾经用于构造某一具体的发放版本;可能还有其它视图浏览该元素用于修复错误的版本。
      此外,那些不受ClearCase版本控制的所有的文件和目录(标准文件、本地的脚本和程序,等。),也都可以通过视图进行浏览。从而使得ClearCase成为开发者的好友,当他们使用视图浏览数据文件、修改框架脚本、编译程序时,通过使用扩展视图的路径名或扩展版本的路径名,开发者可以提高透明度。扩展视图路径名可以覆盖当前视图并且可以访问当前出现在其它视图中的元素的版本扩展版本路径名是一种独立的视图,它可以通过版本树的位置或版本标签定制一个特殊的版本,而不管该版本究竟出现在哪个视图中。
    从没有安装ClearCase的主机平台进行视图访问
      在局域网中ClearCase所控制的数据对于未安装ClearCase的机器也可使用。比如:一个ClearCaseUNIX主机可以通过一种特殊的视图输出VOB;而网上的其他主机可以通过NFS机制连接它。这样它就让开发者在未安装ClearCase的主机平台上使用自己的工具对视图进行读写访问,编译并建立自己的应用。未安装ClearCase的主机必须重新注册或使用安装ClearCase的UNIX主机上的X-Windows系统做检入、检出操作。
    展开全文
  • nginx 功能介绍 Nginx因为它的稳定性、丰富的模块库、灵活的配置和低系统资源的消耗而闻名.业界一致认为它是Apache2.2+mod_proxy_balancer的轻量级代替者,不仅是因为响应静态页面的速度非常快,而且它的模块数量...

    nginx 功能介绍

    Nginx因为它的稳定性、丰富的模块库、灵活的配置和低系统资源的消耗而闻名.业界一致认为它是Apache2.2+mod_proxy_balancer的轻量级代替者,不仅是因为响应静态页面的速度非常快,而且它的模块数量达到Apache的近2/3。对proxy和rewrite模块的支持很彻底,还支持mod_fcgi、ssl、vhosts ,适合用来做mongrel clusters的前端HTTP响应。
    nginx和Apache一样使用模块化设计,nginx模块包括内置模块和第三方模块,其中内置模块中包含主模块和事件模块。

    nginx处理请求逻辑图
    Nginx模块的HTTP请求和响应过程

    nginx可以提供的服务

    1. web 服务.
    2. 负载均衡 (反向代理)
    3. web cache(web 缓存)

    nginx 的优点

    1. 高并发。静态小文件
    2. 占用资源少。2万并发、10个线程,内存消耗几百M。
    3. 功能种类比较多。web,cache,proxy。每一个功能都不是特别强。
    4. 支持epoll模型,使得nginx可以支持高并发。
    5. nginx 配合动态服务和Apache有区别。(FASTCGI 接口)
    6. 利用nginx可以对IP限速,可以限制连接数。
    7. 配置简单,更灵活。

    nginx应用场合

    1. 静态服务器。(图片,视频服务)另一个lighttpd。并发几万,html,js,css,flv,jpg,gif等。
    2. 动态服务,nginx——fastcgi 的方式运行PHP,jsp。(PHP并发在500-1500,MySQL 并发在300-1500)。
    3. 反向代理,负载均衡。日pv2000W以下,都可以直接用nginx做代理。
    4. 缓存服务。类似 SQUID,VARNISH。

    主流web服务产品对比说明

    Apache-特性

    1. 2.2版本本身稳定强大,据官方说:其2.4版本性能更强。
    2. prefork模式取消了进程创建开销,性能很高。
    3. 处理动态业务数据时,因关联到后端的引擎和数据库,瓶颈不在与Apache本身。
    4. 高并发时消耗系统资源相对多一些。
    5. 基于传统的select模型。
    6. 扩展库,DSO方法。

    nginx-特性

    1. 基于异步IO模型,(epoll,kqueue),性能强,能够支持上万并发。
    2. 对小文件支持很好,性能很高(限静态小文件1M)。
    3. 代码优美,扩展库必须编译进主程序。
    4. 消耗代码资源比较低。
    5. lighttpd(百度贴吧,豆瓣)
    6. 基于异步IO模式,性能和nginx相近。
    7. 扩展库是SO模式,比nginx要灵活。
      8.通过差距(mod_secdownload)可实现文件URL地址加密。

    web服务产品性能对比测试

    静态数据性能对比

    1. 处理静态文件Apache性能比nginx和lighttpd要差。
    2. nginx在处理小文件优势明显。
    3. 处理静态小文件(小于1M),nginx和lighttpd比Apache更有优势,lighttpd最强。

      动态数据性能对比

    4. 处理动态内容三者相差不大,主要取决于PHP和数据库的压力。
    5. 当处理动态数据时,三者差距不大,从测试结果看,Apache更有优势一点。这是因为处理动态数据能力取决于PHP和后端数据的提供服务能力。也就是说瓶颈不在web服务器上。
    6. 一般PHP引擎支持的并发参考值300-1000,JAVA引擎并发300-1000,数据库的并发300-1000.

    为什么nginx的总体性能比Apache高。

    1. nginx使用最新的epoll和kqueue网络IO模型,而Apache使用床头的select模式。
    2. 目前Linux下能够承受高并发访问的squid、Memcached 都采用的是epoll网络IO模型。

    如何选择WEB服务器:

    静态业务:高并发、采用nginx,lighttpd,根据自己的掌握程度或公司的要求。
    动态业务:采用nginx和Apache均可。
    既有静态业务又有动态业务:nginx或Apache,不要多选要单选。
    动态业务可以由前端代理(haproxy),根据页面元素的类型,向后转发相应的服务器进行处理。
    思想:我们工作都不要追求一步到位,满足需求的前提下,先用,然后逐步完善。
    提示:nginx做web(Apache,lighttpd)、反向代理(haproxy,lvs,nat)及缓存服务器(squid)也是不错的。
    最终建议:对外的业务nginx,对内的业务Apache(yum httpd mysql-server php)。

    nginx安装

    安装依赖包

    • nginx安装依赖GCC、openssl-devel、pcre-devel和zlib-devel软件库。
    • Pcre全称(Perl Compatible Regular Expressions),中文perl兼容正则表达式,pcre官方站点
    yum install  pcre pcre-devel -y 
    yum install openssl openssl-devel -y 

    开始编译

    使用./configure --help查看各个模块的使用情况,使用--without-http_ssi_module的方式关闭不需要的模块。可以使用--with-http_perl_modules方式安装需要的模块。

    编译命令

    tar -zxf nginx-1.10.1.tar.gz 
    cd nginx-1.10.1/
    ./configure --prefix=/data/app/nginx-1.10.1 --user=nginx --group=nginx  --with-http_ssl_module  --with-http_stub_status_module
    
    useradd nginx -M -s /sbin/nologin 
    make && make install 
    ln -s /data/app/nginx-1.10.1 /data/app/nginx

    测试nginx配置文件是否正常

    /data/app/nginx/sbin/nginx -t 
    nginx: the configuration file /data/app/nginx-1.10.1/conf/nginx.conf syntax is ok
    nginx: configuration file /data/app/nginx-1.10.1/conf/nginx.conf test is successful

    启动nginx服务器

    /data/app/nginx/sbin/nginx  -t  ##检查配置文件
    /data/app/nginx/sbin/nginx      ##确定nginx服务
    netstat -lntup |grep nginx        ## 检查进程是否正常
    curl 192.168.56.12                ## 确认结果

    nginx其他命令

    nginx -s signal
    signal:
    stop — fast shutdown
    quit — graceful shutdown
    reload — reloading the configuration file
    reopen — reopening the log files
    用来打开日志文件,这样nginx会把新日志信息写入这个新的文件中

    /data/app/nginx/sbin/nginx -V 查看已经编译的参数。

    使用kill命令操作nginx。格式:kill -信号 PID

    信号名称

    • TERM,INT 快速关闭
    • QUIT 优雅的关闭,保持吸纳有的客户端连接
    • HUP 重启应用新的配置文件
    • USR1 重新打开日志文件
    • USR2 升级程序
    • WINCH 优雅的关闭工作进程

    例子

    kill -QUIT  `cat /data/app/nginx/nginx.pid`
    kill -HUP `cat /data/app/nginx/nginx.pid`

    nginx配置文件

    配置基础配置文件

    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        server {
            listen       80;
            server_name  localhost;
            location / {
                root   html;
                index  index.html index.htm;
            }
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    }
    ### 测试配置文件是否正常
    shell> /data/app/nginx/sbin/nginx -t 
    nginx: the configuration file /data/app/nginx-1.10.3/conf/nginx.conf syntax is ok
    nginx: configuration file /data/app/nginx-1.10.3/conf/nginx.conf test is successful
    shell> curl -I http://192.168.56.12
    HTTP/1.1 200 OK

    nginx监控

    开启nginx的监控服务

    开启状态页

           #设定查看Nginx状态的地址   
           location /NginxStatus {  
            stub_status on;   
            access_log off;   
            # auth_basic "NginxStatus";   
            # auth_basic_user_file conf/htpasswd;   
           }
    • stub_status on; 表示开启stubStatus的工作状态统计功能。
    • access_log off; 关闭access_log 日志记录功能。
    • auth_basic "NginxStatus"; auth_basic 是nginx的一种认证机制。
    • auth_basic_user_file conf/htpasswd; 用来指定密码文件的位置。

      配置登录密码

    yum install -y httpd-tools
    /usr/local/apache/bin/htpasswd -c /data/app/nginx/conf/htpasswd biglittleant 
    New password:

    完成后会在/data/app/nginx/conf/目录下生成htpasswd文件。

    访问URL

    # curl http://127.0.0.1/NginxStatus
    Active connections: 11921 
    server accepts handled requests
     11989 11989 11991 
    Reading: 0 Writing: 7 Waiting: 42
    • active connections – 活跃的连接数量
    • server accepts handled requests — 总共处理了11989个连接 , 成功创建11989次握手, 总共处理了11991个请求
    • Reading — 读取客户端的连接数.
    • Writing — 响应数据到客户端的数量
    • Waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.

      编写zabbix监控脚本

    nginx_status_fun(){
        NGINX_PORT=$1
        NGINX_COMMAND=$2
        nginx_active(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| grep 'Active' | awk '{print $NF}'
            }
        nginx_reading(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| grep 'Reading' | awk '{print $2}'
           }
        nginx_writing(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| grep 'Writing' | awk '{print $4}'
           }
        nginx_waiting(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| grep 'Waiting' | awk '{print $6}'
           }
        nginx_accepts(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| awk NR==3 | awk '{print $1}'
           }
        nginx_handled(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| awk NR==3 | awk '{print $2}'
           }
        nginx_requests(){
            /usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/NginxStatus/" 2>/dev/null| awk NR==3 | awk '{print $3}'
           }
        case $NGINX_COMMAND in
            active)
                nginx_active;
                ;;
            reading)
                nginx_reading;
                ;;
            writing)
                nginx_writing;
                ;;
            waiting)
                nginx_waiting;
                ;;
            accepts)
                nginx_accepts;
                ;;
            handled)
                nginx_handled;
                ;;
            requests)
                nginx_requests;
            esac 
    }

    nginx优化

    nginx内核优化

    net.ipv4.tcp_fin_timeout = 2
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_keepalive_time = 600
    net.ipv4.ip_local_port_range = 4000    65000
    net.ipv4.tcp_max_syn_backlog = 16384
    net.ipv4.tcp_max_tw_buckets = 36000
    net.ipv4.route.gc_timeout = 100
    net.ipv4.tcp_syn_retries = 1
    net.ipv4.tcp_synack_retries = 1
    net.core.somaxconn = 16384
    net.core.netdev_max_backlog = 16384
    net.ipv4.tcp_max_orphans = 16384
    #以下参数是对iptables防火墙的优化,防火墙不开会提示,可以忽略不理。
    net.ipv4.ip_conntrack_max = 25000000
    net.ipv4.netfilter.ip_conntrack_max=25000000
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=120
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=60
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120

    报错汇总

    问题1:编译报错

    ./configure: error: the HTTP rewrite module requires the PCRE library.
    You can either disable the module by using —without-http_rewrite_module(伪静态)
    option, or install the PCRE library into the system, or build the PCRE library
    statically from the source with nginx by using --with-pcre=<path> option
    yum install  pcre pcre-devel -y

    问题2: 提示找不到libpcre.so.1

    解决:

    1. find / -name libpcre.so*
    2. 将找到的路径 追加到 /etc/ld.so.conf
    3. ldconfig 生效。
    4. ln -s /ser/local/lib/libpcre.so.l /lib64
    5. 或编译时指定源码的安装路径:--with-pcre=/data/tools/pcre-8.33
    6. 最终解决方案 yum install pcre-devel -y 不会出现上述报错。

    问题3:启动nginx报错

    [root@centos6 tools]# /application/nginx/sbin/nginx 
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] still could not bind()

    解决办法:(因为开启了Apache服务)

    [root@nfs-client application]# lsof -i :80 
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    httpd   35833  www    4u  IPv6 129886      0t0  TCP *:http (LISTEN)
    httpd   35834  www    4u  IPv6 129886      0t0  TCP *:http (LISTEN)
    httpd   98511 root    4u  IPv6 129886      0t0  TCP *:http (LISTEN)
    [root@nfs-client application]# /application/apache/bin/apachectl stop 
    [root@nfs-client application]# /application/nginx/sbin/nginx ##重新启动nginx。

    扩展阅读:

    nginx全局变量

    • $args:这个变量等于请求行中的参数,同$query_string。
    • $is_args: 如果已经设置$args,则该变量的值为"?",否则为""。
    • $content_length: 请求头中的Content-length字段。
    • $content_type: 请求头中的Content-Type字段。
    • $document_uri: 与$uri相同。
    • $document_root: 当前请求在root指令中指定的值。
    • $host: 请求主机头字段,否则为服务器名称。
    • $http_user_agent: 客户端agent信息。
    • $http_cookie: 客户端cookie信息。
    • $limit_rate: 这个变量可以限制连接速率。
    • $request_method: 客户端请求的动作,通常为GET或POST。
    • $remote_addr: 客户端的IP地址。
    • $remote_port: 客户端的端口。
    • $remote_user: 已经经过Auth Basic Module验证的用户名。
    • $request_body_file`: 客户端请求主体的临时文件名。
    • $request_uri: 请求的URI,带参数
    • $request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。
    • $scheme: 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
    • $server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
    • $server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。
    • $server_name: 服务器名称。
    • $server_port: 请求到达服务器的端口号。
    • $request_uri: 包含请求参数的原始URI,不包含主机名,如:/foo/bar.php?arg=baz
    • $uri: 不带请求参数的当前URI,$uri不包含主机名,如/foo/bar.html可能和最初的值有不同,比如经过重定向之类的。

    例子:

    访问链接是:http://localhost:88/test1/test2/test.php 
    网站路径是:/var/www/html
    
    $host:localhost
    $server_port:88
    $request_uri:http://localhost:88/test1/test2/test.php
    $document_uri:/test1/test2/test.php
    $document_root:/var/www/html
    $request_filename:/var/www/html/test1/test2/test.php

    nginx plus -- ngx_http_status_module

    商业版的 nginx plus 通过他的 ngx_http_status_module 提供了比 nginx 更多的监控指标,可以参看 http://demo.nginx.com/status.html

    nginx access log 分析

    nginx 的 access log 中可以记录很多有价值的信息,通过分析 access log,可以收集到很多指标。
    python 编写的 linux 工具 ngxtop 就实现了对 access log 的分析功能。

    web服务器事件处理模型

    select

    select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。
    select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一。
    select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。
    另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销。

    poll

    poll在1986年诞生于System V Release 3,它和select在本质上没有多大差别,但是poll没有最大文件描述符数量的限制。
    poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。
    另外,select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)。

    epoll

    直到Linux2.6才出现了由内核直接支持的实现方法,那就是epoll,它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。
    epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。
    epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。
    另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。

    nginx -s reload 过程

    nginx主进程读取配置文件,如果发现配置文件变更,会创建一个新的主进程,然后同时旧的进程,及旧的子进程关闭,旧进程会拒绝新的连接,服务到自己的连接结束,然后关闭。

    Apache select模型和 nginx epoll 模型对比讲解

    Nginx的高并发得益于其采用了epoll模型,与传统的服务器程序架构不同,epoll是linux内核2.6以后才出现的。下面通过比较Apache和Nginx工作原理来比较。

    传统Apache都是多进程或者多线程来工作,假设是多进程工作(prefork),apache会先生成几个进程,类似进程池的工作原理,只不过这里的进程池会随着请求数目的增加而增加。对于每一个连接,apache都是在一个进程内处理完毕。具体是 recv(),以及根据 URI 去进行磁盘I/O来寻找文件,还有 send()都是阻塞的。其实说白了都是 apche 对于套接字的I/O,读或者写,但是读或者写都是阻塞的,阻塞意味着进程就得挂起进入sleep状态,那么一旦连接数很多,Apache必然要生成更多的进程来响应请求,一旦进程多了,CPU对于进程的切换就频繁了,很耗资源和时间,所以就导致apache性能下降了,说白了就是处理不过来这么多进程了。其实仔细想想,如果对于进程每个请求都没有阻塞,那么效率肯定会提高很多。

    Nginx采用epoll模型,异步非阻塞。对于Nginx来说,把一个完整的连接请求处理都划分成了事件,一个一个的事件。比如accept(), recv(),磁盘I/O,send()等,每部分都有相应的模块去处理,一个完整的请求可能是由几百个模块去处理。真正核心的就是事件收集和分发模块,这就是管理所有模块的核心。只有核心模块的调度才能让对应的模块占用CPU资源,从而处理请求。拿一个HTTP请求来说,首先在事件收集分发模块注册感兴趣的监听事件,注册好之后不阻塞直接返回,接下来就不需要再管了,等待有连接来了内核会通知你(epoll的轮询会告诉进程),cpu就可以处理其他事情去了。一旦有请求来,那么对整个请求分配相应的上下文(其实已经预先分配好),这时候再注册新的感兴趣的事件(read函数),同样客户端数据来了内核会自动通知进程可以去读数据了,读了数据之后就是解析,解析完后去磁盘找资源(I/O),一旦I/O完成会通知进程,进程开始给客户端发回数据send(),这时候也不是阻塞的,调用后就等内核发回通知发送的结果就行。整个下来把一个请求分成了很多个阶段,每个阶段都到很多模块去注册,然后处理,都是异步非阻塞。异步这里指的就是做一个事情,不需要等返回结果,做好了会自动通知你。

    select/epoll的特点

    select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。但是如果连接很少的情况下, select和epoll的LT触发模式相比, 性能上差别不大。
    这里要多说一句,select支持的句柄数是有限制的, 同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,很可能导致溢出,而且非常不容易发现问题, 当然可以通过修改linux的socket内核调整这个参数。
    epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。
    对于epoll而言还有ET和LT的区别,LT表示水平触发,ET表示边缘触发,两者在性能以及代码实现上差别也是非常大的。

    可以举一个简单的例子来说明Apache的工作流程,我们平时去餐厅吃饭。餐厅的工作模式是一个服务员全程服务客户,流程是这样,服务员在门口等候客人(listen),客人到了就接待安排的餐桌上(accept),等着客户点菜(request uri),去厨房叫师傅下单做菜(磁盘I/O),等待厨房做好(read),然后给客人上菜(send),整个下来服务员(进程)很多地方是阻塞的。这样客人一多(HTTP请求一多),餐厅只能通过叫更多的服务员来服务(fork进程),但是由于餐厅资源是有限的(CPU),一旦服务员太多管理成本很高(CPU上下文切换),这样就进入一个瓶颈。

    再来看看Nginx得怎么处理?餐厅门口挂个门铃(注册epoll模型的listen),一旦有客人(HTTP请求)到达,派一个服务员去接待(accept),之后服务员就去忙其他事情了(比如再去接待客人),等这位客人点好餐就叫服务员(数据到了read()),服务员过来拿走菜单到厨房(磁盘I/O),服务员又做其他事情去了,等厨房做好了菜也喊服务员(磁盘I/O结束),服务员再给客人上菜(send()),厨房做好一个菜就给客人上一个,中间服务员可以去干其他事情。整个过程被切分成很多个阶段,每个阶段都有相应的服务模块。我们想想,这样一旦客人多了,餐厅也能招待更多的人。

    不管是Nginx还是Squid这种反向代理,其网络模式都是事件驱动。事件驱动其实是很老的技术,早期的select、poll都是如此。后来基于内核通知的更高级事件机制出现,如libevent里的epoll,使事件驱动性能得以提高。事件驱动的本质还是IO事件,应用程序在多个IO句柄间快速切换,实现所谓的异步IO。事件驱动服务器,最适合做的就是这种IO密集型工作,如反向代理,它在客户端与WEB服务器之间起一个数据中转作用,纯粹是IO操作,自身并不涉及到复杂计算。反向代理用事件驱动来做,显然更好,一个工作进程就可以run了,没有进程、线程管理的开销,CPU、内存消耗都小。

    所以Nginx、Squid都是这样做的。当然,Nginx也可以是多进程 + 事件驱动的模式,几个进程跑libevent,不需要Apache那样动辄数百的进程数。Nginx处理静态文件效果也很好,那是因为静态文件本身也是磁盘IO操作,处理过程一样。至于说多少万的并发连接,这个毫无意义。随手写个网络程序都能处理几万的并发,但如果大部分客户端阻塞在那里,就没什么价值。

    再看看Apache或者Resin这类应用服务器,之所以称他们为应用服务器,是因为他们真的要跑具体的业务应用,如科学计算、图形图像、数据库读写等。它们很可能是CPU密集型的服务,事件驱动并不合适。例如一个计算耗时2秒,那么这2秒就是完全阻塞的,什么event都没用。想想MySQL如果改成事件驱动会怎么样,一个大型的join或sort就会阻塞住所有客户端。这个时候多进程或线程就体现出优势,每个进程各干各的事,互不阻塞和干扰。当然,现代CPU越来越快,单个计算阻塞的时间可能很小,但只要有阻塞,事件编程就毫无优势。所以进程、线程这类技术,并不会消失,而是与事件机制相辅相成,长期存在。

    总言之,事件驱动适合于IO密集型服务,多进程或线程适合于CPU密集型服务,它们各有各的优势,并不存在谁取代谁的倾向。

    参考

    详解 Nginx+Linux 性能调优

     

    展开全文
  • AOP之基于Schema配置总结与案例

    千次阅读 2015-04-24 10:16:22
    AOP从Spring2.0之后通过“aop”命名空间来定义切面、切入点及声明通知。在Spring配置文件中,所以AOP相关定义必须放在标签下,该标签下可以有、、标签,配置顺序不可变。

    林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

      一、AOP的一些概念

             AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

           而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。所谓“切面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向切面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“切面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

          使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

          实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“切面”,从而使得编译器可以在编译期间织入有关“切面”的代码。然而殊途同归,实现AOP的技术特性却是相同的,分别为:

          1、join point(连接点):是程序执行中的一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个join point。
          2、point cut(切入点):本质上是一个捕获连接点的结构。在AOP中,可以定义一个point cut,来捕获相关方法的调用。
          3、advice(通知):是point cut的执行代码,是执行“切面”的具体逻辑。
          4、aspect(切面):point cut和advice结合起来就是aspect,它类似于OOP中定义的一个类,但它代表的更多是对象间横向的关系。
          5、introduce(引入):为对象引入附加的方法或属性,从而达到修改对象结构的目的。有的AOP工具又将其称为mixin。

          6、AOP代理(AOP Proxy):AOP框架创建的对象,这个对象通常可以作为目标对象的替代品,而AOP代理提供比目标对象更加强大的功能。真实的情形是,当应用调用AOP代理的方法时,AOP代理会在自己的方法中回调目标对象的方法,从而完成应用的调用。关于AOP代理的典型例子就是Spring中的事务代理Bean。通常,目标Bean的方法不是事务性的,而AOP代理包含目标Bean的全部方法,而且这 些方法经过加强变成了事务性方法。简单地说,目标对象是蓝本,AOP代理是目标对象的加强,在目标对象的基础上,增加属性和方法,提供更强大的功能。
    目标对象包含一系列切入点。切入点可以触发处理连接点集合。用户可以自己定义切入点,如使用正则表达式。AOP代理包装目标对象,在切入点处加入处理。在切入点加入的处理,使得目标对象的方法功能更强。Spring 默认使用JDK动态代理实现AOP代理,主要用于代理接口。也可以使用CGLIB代理。实现类的代理,而不是接口。如果业务对象没有实现接口,默认使用 CGLIB代理。但面向接口编程是良好的习惯,尽量不要面向具体类编程。因此,业务对象通常应实现一个或多个接口。

          7、目标对象(Target Object):包含一个连接点的对象,也被称为代理对象。
          8、 前置通知(Before advice):在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。
          9、后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。
          10、返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。ApplicationContext中在<aop:aspect>里面使用<after-returning>元素进行声明。
          11、环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。

          12、抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。 ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。

         Spring2.0目前只支持使用方法调用作为连接点(join point)。

         Spring 定义切入点语法:excution(modifiers-pattern?ret-type-pattern declaring-type-pattern ?name-pattern(param-pattern)throws-pattern?)

          除了ret-type-pattern (即返回类型模式)、name-pattern(param-pattern)(名字模式和参数模式)外,其他模式都是可选的。返回类型模式决定了方法的返回类型必须依次匹配一个连接点(即一个方法)。使用最频繁的一个返回类型模式是*,它代表了匹配任意的返回类型。如果写明了返回类型,比如String,那么只能匹配返回String类型的连接点(方法)。名字模式匹配的是方法名。你可以用*通配符表示匹配所有方法名。参数模式中,()表示匹配了不接受任何参数的方法,而(。。)表示匹配任意数量参数的方法。模式(*)表示匹配任意类型参数的方法。模式(*,String)表示匹配:第一个为任意参数类型,第二个必须为String类型的方法。


    二、基于Schema(XML)的AOP配置

    AOP从Spring2.0之后通过“aop”命名空间来定义切面、切入点及声明通知。

     在Spring配置文件中,所以AOP相关定义必须放在<aop:config>标签下,该标签下可以有<aop:pointcut>、<aop:advisor>、<aop:aspect>标签,配置顺序不可变。

    • <aop:pointcut>:用来定义切入点,该切入点可以重用;
    • <aop:advisor>:用来定义只有一个通知和一个切入点的切面;
    • <aop:aspect>:用来定义切面,该切面可以包含多个切入点和通知,而且标签内部的通知和切入点定义是无序的;和advisor的区别就在此,advisor只包含一个通知和一个切入点。


    声明切面 
        切面就是包含切入点和通知的对象,在Spring容器中将被定义为一个Bean,xml形式的切面需要一个切面支持Bean,该支持Bean的字段和方法提供了切面的状态和行为信息,并通过配置方式来指定切入点和通知实现。 
        切面使用<aop:aspect>标签指定,ref属性用来引用切面支持Bean。

    声明切入点 
        切入点在Spring中也是一个Bean,Bean定义方式可以有很三种方式: 
    ● 在<aop:config>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,对于需要共享使用的切入点最好使用该方式,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式。 
    ● 在<aop:aspect>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,但一般该切入点只被该切面使用,当然也可以被其他切面使用,但最好不要那样使用,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式 
    ● 匿名切入点Bean,可以在声明通知时通过pointcut属性指定切入点表达式,该切入点是匿名切入点,只被该通知使用 

        <aop:config>    
         <aop:aspect ref="aspectSupportBean">    
             <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterAdvice"/>    
         </aop:aspect>  
        </aop:config>   


    声明通知:(前置通知,后置通知,环绕通知) 
    1、前置通知:在切入点选择的连接点处的方法之前执行的通知,该通知不影响正常程序执行流程(除非该通知抛出异常,该异常将中断当前方法链的执行而返回)。 
    Spring中在切入点选择的方法之前执行,通过<aop:aspect>标签下的<aop:before>标签声明: 

        <aop:before pointcut="切入点表达式" (或者pointcut-ref="切入点Bean引用")   
             method="前置通知实现方法名" arg-names="前置通知实现方法参数列表参数名字"/>  
    ● pointcut和pointcut-ref:二者选一,指定切入点; 
    ● method:指定前置通知实现方法名,如果是多态需要加上参数类型,多个用“,”隔开,如beforeAdvice(java.lang.String); 
    ● arg-names:指定通知实现方法的参数名字,多个用“,”分隔,可选,切入点中使用“args(param)”匹配的目标方法参数将自动传递给通知实现方法同名参数。 

    2、后置通知:在切入点选择的连接点处的方法之后执行的通知,包括如下类型的后置通知: 
    ● 后置返回通知:在切入点选择的连接点处的方法正常执行完毕时执行的通知,必须是连接点处的方法没抛出任何异常正常返回时才调用后置通知。 
    在切入点选择的方法正常返回时执行,通过<aop:aspect>标签下的<aop:after-returning>标签声明: 

    <aop:after-returning pointcut="切入点表达式"  pointcut-ref="切入点Bean引用"    
            method="后置返回通知实现方法名"    
            arg-names="后置返回通知实现方法参数列表参数名字"    
            returning="返回值对应的后置返回通知实现方法参数名"    
    />
    3、后置异常通知:在切入点选择的连接点处的方法抛出异常返回时执行的通知,必须是连接点处的方法抛出任何异常返回时才调用异常通知。 
    在切入点选择的方法抛出异常时执行,通过<aop:aspect>标签下的<aop:after-throwing>标签声明: 

    <aop:after-throwing pointcut="切入点表达式"  pointcut-ref="切入点Bean引用"    
                                    method="后置异常通知实现方法名"    
                                    arg-names="后置异常通知实现方法参数列表参数名字"    
                                    throwing="将抛出的异常赋值给的通知实现方法参数名"/> 
    4、后置最终通知:在切入点选择的连接点处的方法返回时执行的通知,不管抛没抛出异常都执行,类似于Java中的finally块。 
    在切入点选择的方法返回时执行,不管是正常返回还是抛出异常都执行,通过<aop:aspect>标签下的<aop:after >标签声明: 

        <aop:after pointcut="切入点表达式"  pointcut-ref="切入点Bean引用"    
                          method="后置最终通知实现方法名"    
                          arg-names="后置最终通知实现方法参数列表参数名字"/>   
    5、环绕通知:环绕着在切入点选择的连接点处的方法所执行的通知,环绕通知可以在方法调用之前和之后自定义任何行为,并且可以决定是否执行连接点处的方法、替换返回值、抛出异常等等。 
    环绕着在切入点选择的连接点处的方法所执行的通知,环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值,可通过<aop:aspect>标签下的<aop:around >标签声明: 


        <aop:around pointcut="切入点表达式"  pointcut-ref="切入点Bean引用"    
                             method="后置最终通知实现方法名"    
                             arg-names="后置最终通知实现方法参数列表参数名字"/>  

    环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型,在通知实现方法内部使用ProceedingJoinPoint的proceed()方法使目标方法执行,proceed 方法可以传入可选的Object[]数组,该数组的值将被作为目标方法执行时的参数。 

    引入 
        Spring允许为目标对象引入新的接口,通过在< aop:aspect>标签内使用< aop:declare-parents>标签进行引入,定义方式如下: 
        <aop:declare-parents    
                  types-matching="AspectJ语法类型表达式"    
                  implement-interface=引入的接口"                 
                  default-impl="引入接口的默认实现"    
                  delegate-ref="引入接口的默认实现Bean引用"/>  

    Advisor 
    Advisor表示只有一个通知和一个切入点的切面,由于Spring AOP都是基于AOP的拦截器模型的环绕通知的,所以引入Advisor来支持各种通知类型(如前置通知等5种),Advisor概念来自于Spring1.2对AOP的支持,在AspectJ中没有相应的概念对应。 
    Advisor可以使用<aop:config>标签下的<aop:advisor>标签定义: 


        <aop:advisor pointcut="切入点表达式" pointcut-ref="切入点Bean引用"    
                             advice-ref="通知API实现引用"/>  
          
        <bean id="beforeAdvice" class="cn.javass.spring.chapter6.aop.BeforeAdviceImpl"/>  
        <aop:advisor pointcut="execution(* cn.javass..*.sayAdvisorBefore(..))"    
                             advice-ref="beforeAdvice"/>   

    三、使用范例

    本文工程下载


    一定要注意导入这些包!

    aspectjweaver.jar

    aopalliance-1.0.jar


    1、人的接口类

    package com.mucfc;
    /**  
    *功能  人的接口类
    *作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
    *时间 2015.4.24 
    */
    public interface Person {
    	public void eatBreakfast();
    	public void eatLunch();
    	public void eatSupper();
    	
    
    }
    
    2、Baby实现类

    package com.mucfc;
    /**  
    *功能  人的实现类
    *作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
    *时间 2015.4.24 
    */
    public class BabyPerson implements Person{
    
    	@Override
    	public void eatBreakfast() {
    		System.out.println("小Baby正在吃早餐");
    	}
    
    	@Override
    	public void eatLunch() {
    		System.out.println("小Baby正在吃午餐");
    	}
    
    	@Override
    	public void eatSupper() {
    		System.out.println("小Baby正在吃晚餐");
    	}
    
    }
    

    3、然后把要增强的方法都写在一个文件中去

    package com.mucfc;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class AdivceMethod {
    public void beforeEat(){
    	System.out.println("-------------------吃饭之前先洗小手!--------------------");
    }
    public void afterEat(){
    	System.out.println("-------------------午饭吃完要睡午觉!--------------------");
    }
    public Object aroundEat(ProceedingJoinPoint pjp) throws Throwable{
    	  System.out.println("-------------------吃晚饭前先玩一玩!-------------------");  
    	  Object retVal = pjp.proceed();  
    	  System.out.println("-------------------晚饭吃完后要得睡觉了!-------------------"); 
    	  return retVal;
    }
    }
    

    4、下面就是重点了,直接使用aop:config

    <?xml version="1.0" encoding="UTF-8"?>
    <beans  xmlns="http://www.springframework.org/schema/beans"  
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
            xmlns:aop="http://www.springframework.org/schema/aop"  
            xsi:schemaLocation="  
               http://www.springframework.org/schema/beans  
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
               http://www.springframework.org/schema/aop  
               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
               
          <bean id="babyPerson" class="com.mucfc.BabyPerson"/><!-- 被增强的bean -->
          <bean id="adviceAspect" class="com.mucfc.AdivceMethod"/><!-- 增强方法的bean -->
    
         <aop:config  proxy-target-class="true">  
         <aop:pointcut id="pointcut" expression="execution(* com.mucfc.BabyPerson.*(..))"/>  <!-- 定义切点 -->
         <aop:aspect ref="adviceAspect">  <!-- 定义切面 -->
            <aop:before method="beforeEat" pointcut-ref="pointcut" />  <!-- 定义前置增强方法 -->
            <aop:after method="afterEat" pointcut="execution(* com.mucfc.BabyPerson.eatLunch(..))"/><!--定义后置增加,使用匿名切点  -->
            <aop:around method="aroundEat" pointcut="execution(* com.mucfc.BabyPerson.eatSupper(..))"/><!--定义后置增加,使用匿名切点  -->
         </aop:aspect>  
        </aop:config>
        
       
    
    </beans>
    

    5、测试

    package com.mucfc;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
    
    	public static void main(String[] args) {
    		ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
           Person babyPerson=(BabyPerson)context.getBean("babyPerson");
            babyPerson.eatBreakfast();
            babyPerson.eatLunch();
            babyPerson.eatSupper();
            
    	}
    
    }
    
    结果:

    基于XML的配置方法实现很方便,比上一讲的基于API的方法简单多了,而且代码看起来更容易解决,做到这里。不得不佩服Spring的强大!

    本文工程下载

    林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

    展开全文
  • 本文原创作者:strongerHuang版权所有,未经允许,禁止用于其它商业用途!!! Ⅰ、写作前面关于FreeRTOSConfig.h配置文件里面的内容除了“通用配置”之外,其他配置的内容初学者用的相对较少,理解起来也相对难...

    本文原创作者:strongerHuang

    版权所有,未经允许,禁止用于其它商业用途!!!

     

    Ⅰ、写作前面

    关于FreeRTOSConfig.h配置文件里面的内容除了“通用配置”之外,其他配置的内容初学者用的相对较少,理解起来也相对难一点。为了让初学者有一个大概的了解,本文依然继续讲述关于FreeRTOSConfig.h配置的内容,后期会结合应用更进一步讲述关于FreeRTOSConfig.h的内容。

     

    FreeRTOSConfig.h配置文件(一)_通用配置

     

    FreeRTOSConfig.h配置文件(二)_HOOK钩子函数

     

    Ⅱ、TIMERS配置

    TIMER即定时器,在RTOS中的TIMER属于软件定时。FreeRTOS的定时器精度不高,会随着定时的增加而改变,特别是TIMER任务优先级较低,高优先级占用资源的情况下。

    若要使用高精度的定时,还是最后使用硬件的定时器(现在处理器一般都有多个硬件TIMER)。

     

    1.configUSE_TIMERS

    是否使用软件定时器

     

    配置为0:不使用

    配置为1:使用

     

    其他许多相关的功能都需要结合该配置才能使用,使用时需要注意是否关联。

     

    2.configTIMER_TASK_PRIORITY

    软件定时器任务优先级

     

    软件定时器其实也是需要创建一个任务,创建方式和我们常规的一样,只是它是有系统内核完成,不用我们自己写创建任务代码。

    这里的这个优先级就是定时器任务的优先级。

     

    3.configTIMER_QUEUE_LENGTH

    软件定时器命令队列长度

     

    关于TIMER的命令队列牵涉的知识相对复杂点,后期进一步讲述,可看下图:

     

    4.configTIMER_TASK_STACK_DEPTH

    分配给软件定时器的堆栈空间

     

    Ⅲ、CO_ROUTINES配置

    CO_ROUTINES这个不好翻译,网上都叫协同程序,或者合作程序,理解为协同一起使用的程序,后期结合应用讲述。

     

    1.configUSE_CO_ROUTINES

    是否使用CO_ROUTINES

     

    配置为0:不使用

    配置为1:使用

     

    2.configMAX_CO_ROUTINE_PRIORITIES

    CO_ROUTINE优先级

     

    Ⅳ、MEMORY配置

    内存分配相关的配置,这里的配置与heap_x.c有关,后面会再次进行讲述。

     

    1.configSUPPORT_STATIC_ALLOCATION

    是否支持静态分配

     

    配置为0:不支持

    配置为1:支持

     

    2.configSUPPORT_DYNAMIC_ALLOCATION

    是否支持动态分配

     

    配置为0:不支持

    配置为1:支持

     

    3.configTOTAL_HEAP_SIZE

    分配给系统的堆栈

     

    创建任务,堆栈,静态、动态都分配的内存都来自这里。

     

    4.configAPPLICATION_ALLOCATED_HEAP

    APP使用哪里分配的堆

     

    配置为0:使用系统分配的堆

    配置为1:使用外部分配的堆

     

    默认使用系统分配的堆,见下面定义:

     

    #if(configAPPLICATION_ALLOCATED_HEAP== 1 )

      extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];

    #else

      static uint8_t ucHeap[configTOTAL_HEAP_SIZE];

    #endif

     

    Ⅴ、RUN_TIME_STATS配置

    运行时信息统计配置

     

    1.configGENERATE_RUN_TIME_STATS

    是否生成统计信息

     

    配置为0:否

    配置为1:是

     

    2.configUSE_TRACE_FACILITY

    是否协助执行可视化和跟踪

     

    配置为0:否

    配置为1:是

     

    这里会添加额外的结构体来实现。

     

    3.configUSE_STATS_FORMATTING_FUNCTIONS

    是否统计相关的功能

     

    配置为0:否

    配置为1:是

     

    设置宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS为1会编译vTaskList()和vTaskGetRunTimeStats()函数。如果将这两个宏任意一个设置为0,上述两个函数不会被编译。

     

    Ⅵ、其他配置

    这里简单综合讲述一下各项配置

     

    1.configASSERT

    断言配置

     

    2.Interrupt相关

    configKERNEL_INTERRUPT_PRIORITY:内核中断优先级

    configMAX_SYSCALL_INTERRUPT_PRIORITY:系统调用最大的优先级

    configMAX_API_CALL_INTERRUPT_PRIORITY:API调用的最大优先级

     

    这一节与(Cortex)内核硬件中断有关。

     

    3.INCLUDE配置

    #defineINCLUDE_vTaskPrioritySet   1

    #defineINCLUDE_uxTaskPriorityGet  1

    #defineINCLUDE_vTaskDelete       1

     

    这里很好理解,是否包含这一些内容,在UCOS中比较常见。

     

    Ⅶ、最后

    微信搜索“EmbeddDeveloper” 或者扫描下面二维码、关注,在我的底部菜单查看更多精彩内容!

    展开全文
  • 配置web.xml,配置Struts2的过滤器

    千次阅读 2017-12-23 20:18:24
    配置web.xml,配置Struts2的过滤器,例如:   filter>  filter-name>struts2filter-name>  filter-class> org.apache.struts2.dispatcher.FilterDispatcher filter-class> ...
  • 分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!... 网络产品推广和新闻消息推送时,经常用到...例如Wordpress的评论邮件通知功能,每天要发送的邮件数量...
  • FreeRTOS中“FreeRTOSConfig.h”配置的内容随着版本(功能)的增加而增加,也就是说随着系统功能的增加,对应需要的配置信息也响应增加了。但是系统为了兼容之前的代码,系统自身做了兼容处理。   比如 : ...
  • 2017年2月16日,Gartner发布了2017年BI商业智能和分析平台魔力象限报告,本文主要对此进行一些解读,帮助大家更好了解市场状况和趋势。
  • 之前我们对于优动漫PAINT中的颜色配置文件工作进行了简单的介绍,这次我们将对如何使用颜色配置文件功能,及如何在优动漫PAINT中将已描画完成的图像保存为CMYK格式数据等进行实例演示。 优动漫PAINT支持CMYK格式的...
  • Tomcat配置技巧

    万次阅读 2005-09-14 11:07:00
    你所需要做的就是:按照你的需求配置Tomcat,只要你正确配置,Tomcat一般都能适合你... 配置系统管理(Admin Web Application) 大多数商业化的J2EE服务器都提供一个功能强大的管理界面,且大都采用易于理解的Web应用界
  • Gitlab安装使用及汉化配置

    万次阅读 2017-05-22 16:51:31
    公司的项目,因为商业层面的原因,需要把代码托管到自有的服务器上,并且服务器很有可能是放在企业内网中,不对公网开放。 出于安全性的考虑,暂时没有使用国内的Git 服务平台的计划。 GitHub 和BitBucket ,...
  • Nginx基础架构和配置

    万次阅读 2019-05-18 22:47:46
    支持热部署,不停机更新配置文件,升级版本,更换日志文件。 低内存消耗,10k keep-alive连接在非活动模式下大概2.5M。 事件驱动模型,Aio,mmap,sendfile。 传统网络传输过程 硬盘 >> kernel buffer >&...
  • DNS服务器搭建与配置

    万次阅读 2018-10-16 13:25:41
    title: DNS服务器搭建与配置 date: 2018-10-15 21:20:07 tags: [Linux笔记,Linux服务] categories: Linux DNS服务介绍 DNS服务简介: DNS(Domain Name System–域名系统),是因特网的一项服务。它作为...
  • IntelliJ IDEA开发环境配置

    万次阅读 多人点赞 2018-07-19 18:32:18
    IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE支持、各类版本工具(git、svn、github等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超常的。...
  • 安装 配置SharePoint Server 2016 的硬件和软件要求 硬件要求:物理服务器的位置 一些企业具有紧密放置的数据中心,它们由高带宽的光纤链路进行连接。在该环境中,可以将两个数据中心配置为单场。该分布式场...
  • 什么是 配置管理

    千次阅读 2008-05-31 17:53:00
    配置管理(Configuration Management,CM)是通过技术或行政手段对软件产品及其开发过程和生命周期进行控制、规范的一系列措施。配置管理的目标是记录软件产品的演化过程,确保软件开发者在软件生命周期中各个阶段都能...
  • 我的vim配置主要有以下优点: 1.按F5可以直接编译并执行C、C++、java代码以及执行shell脚本,按“F8”可进行C、C++代码的调试 2.自动插入文件头 ,新建C、C++源文件时自动插入表头:包括文件名、作者、联系方式、...
  • CentOS 7 环境配置

    千次阅读 2016-06-17 11:06:44
    CentOS 7 环境配置
  • maven私服配置

    千次阅读 2016-04-27 10:42:25
    私服是什么 私服,私有服务器,是公司内部Maven项目经常需要的东东,不总结一下,不足以体现出重视。Nexus是常用的私用Maven服务器,一般是公司内部使用。...Nexus常用功能就是:指定私服的中央地址、将自己的Mave
  • Linux系统的安装与配置

    千次阅读 2019-01-20 16:00:05
    1.1.什么是Linux? 和windows操作系统类似,Linux是一套性能稳定的多用户网络操作系统 ...4.丰富的网络功能 (可以非常方便的搭建各种网络服务(dns(解析域名),dhcp(自动获取IP)),非常适合作为网络...
  • Windows 10配置CUDA 9.2

    万次阅读 2018-08-28 02:13:57
    知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。 目录 Windows 10配置CUDA 9.2 目录 配置环境&平台 配置步骤 第一步:安装Visual Studio 2017 第二步:安装CUDA 9.2 第...
  • geohash之2d 地理空间索引

    千次阅读 2018-06-07 18:37:27
    2d 地理空间索引 概述 2D地理空间索引可以将文档与二维空间中的位置(例如地图上的点)相关联。...地理空间索引支持对坐标字段和 其他字段(例如商业或景点类型)的查询。例如,您可能会写一个查...
  • 新手建站十大免费空间推荐-稳定,可用的免费空间及其使用体验 新手建站十大免费空间推荐-稳定,可用的免费空间及其使用体验   一、OpenShift OpenShift 1、OpenShift空间是Red Hat的平台即服务的云计算平台...
  • 应用服务器配置测算及计算公式

    万次阅读 2019-01-15 10:06:27
    应用服务器配置测算及计算公式 1 术语和定义 1.1 信息系统 由计算机、通信设备、处理设备、控制设备及其相关的配套设施构成,按照一定的应用目的和规则,对信息进行采集、加工、存储、传输、检索等处理的人机系统。...
  • 什么是商业智能?商业智能工具都有哪些? 商业智能也称作BI,是英文单词Business Intelligence的缩写。商业智能通常被理解为将企业中现有的数据转化为知识,帮助企业做出明智的业务经营决策的工具。这里所谈的数据...
  • 社群更具价值的商业模式 目录 第一章 「失控」时代与群体智慧 第二章 社群与社群经济 第三章 社群的商业价值 第四章 社群经济的商业模式 第五章 我们身边的社群 第六章 社群未来时代 思维导图 总结 第一章 ...
  • Tomcat配置技巧Top 10

    千次阅读 2005-12-01 11:21:00
    Tomcat配置技巧Top 10需要做的就是:按照你的需求配置Tomcat,只要你正确配置,Tomcat一般都能适合你的要求。... 配置系统管理(Admin Web Application) 大多数商业化的J2EE服务器都提供一个功能强大的管理界面,且大
  • MySQL软件采用了双授权政策(本词条“授权政策”),它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。由于其社区版的性能...
  • ARM平台上蓝牙协议栈Bluez的移植使用和配置

    万次阅读 多人点赞 2015-10-22 20:50:34
    据说因为此技术尚在萌芽的阶段,故将Bluetooth以“蓝牙”的中文译名在台湾地区进行商业的注册,不过根据英文本身的意义直译,还是“蓝牙”较为贴切。 蓝牙用于在不同的设备之间进行无线连接,例如连接计算机和...
  • 只有拥有一个有效的许可证才可以使用所有功能【专业版本——收费】 https://help.sonatype.com/display/NXRM2/Download+Archives+-+Repository+Manager+2 因此我们首先找到Nexus Repository Manager ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,677
精华内容 25,470
关键字:

商业空间的功能配置