双机问题一则
双机的连接方式就不详说了,就是心跳线连接,A和B机都是两个网卡bge0和bge1。两个网卡配置的相同地址。A和B跑不同的应用,互为主备。
问题:A机或者B机莫名其妙无法远程连入,查看双机状况,发现A机或B机下线。
解决:从A机背板或者远程管理端口连入,机器运行正常,查看/var/adm/messages有些异常,但是感觉没问题,只是一台机器两个网卡间切换而已。
最近用1.1的框架写个简单的测试程序。相信使用的人已经不多了,只是记录下,以后可能有用。
测试由于题目很多,分批显示或者一个题目一个题目显示都不是很完美,所以采用全部显示,测试者选择问题答案之后采用js来控制选择结果。参考了自动改变CheckBoxList选择项目的背景颜色 。我采用DataList嵌套RadioButtonList从数据库读取数据,稍微有些不同。js部分:
<script language="javascript"> function ChangeSelectedItemColor(RadioButtonListNum,RadioButtonListId, numOfItems) { //Get the RadioButtonList object. var objCtrl = document.getElementById('DataList1__ctl' + RadioButtonListNum + '_' + RadioButtonListId); if(objCtrl == null) { return; } for(i = 0; i < numOfItems; i++) { //var name='DataList1__ctl' + checkBoxNum + '_' + checkBoxListId+':'+i; var objItem = document.getElementById('DataList1__ctl' + RadioButtonListNum + '_' + RadioButtonListId + '_' + i); if(objItem.checked) { objItem.parentElement.className = 'ItemBgColor'; } else { objItem.parentElement.className = ''; } } } </script>
代码端:
srbtnlist_stda.Attributes.Add("onclick","ChangeSelectedItemColor('"+ (i+1) +"','srbtnlist_stda','"+srbtnlist_stda.Items.Count+"');");
//srbtnlist_stda是RadioButtonList的id。
自从三年前用.Net1.1的框架写了最后一个ASP.NET的程序后再也没有捣鼓和.NET相关的东西,而是基本都把业余时间投入到了Solaris和Oracle。没想到几天前却发现那个程序被人攻击了。
仔细看过对方服务器配置之后,发现两个问题:
1、原来基于1.1的框架写的,结果应用却跑在2.0下,
2、web.config中的配置错误,导致“管理员”身份登录验证失效。下面是验证代码:
第一个问题,很好解决。卸载IIS的所有.NET版本,然后重新安装。最后配置站点的时候将1.1和2.0分别设置两个程序池。站点属性里一定要设置对,1.1的程序别设成2.0。
第二个问题,当时很迷糊,也没有找到原因。因为程序代码在我本地调试正常,本地和服务器唯一的区别就是我没有安装2.0的框架。最后一句句检查web.config后确认原因,就是web.config中:<add key="dbstring" value="user id=xx; password=xxx; database=xxx; server=xxxx" />server项没有设置对。改之!
本来还想将程序重新测试一下,但是实在觉得得不偿失,1.1多久远的事情了,改明儿用java重写这个站点的程序吧(算是练习java)。这反映一个问题,微软现在都.NET4.0了,如果向下兼容还做成这样,一定要让用户去确定框架,实在不是多完美的事情。
需求:服务器归一个部门管理,但是由于数据的敏感性,所以root帐号不能交给这个部门。所以出现了这样一个需求。关机、重启等特殊命令给一个用户来执行。但是考虑到服务器上脚本的安全性,这个用户又不能去查看这些脚本。
首先,我想到的是Solaris的RABC来实现。通过SMC建立相应的角色,用户,并授权。可能由于我操作的问题,始终都没弄对。
然后一翻google。将能搜索到的办法都基本尝试了一下,居然没有一个可行,继续怀疑自己的问题。其实网上的办法是另外一种,就是通过shell来做文章,登陆后立刻执行一个shell关机,比如(如下办法我没成功):
| 要关机,必须有关机权限。什么人有关机权限?root。但不能把root口令告诉普通用户,怎么办?创建一个特殊的超级用户,他的登录shell是一个定制的文件:一条关机命令。具体做法如下:
# vi /etc/passwd shutdown:x:0:1:shutdown user:/:/bin/shutdown 添加一个用户 # vi /etc/shadow shutdown:::::::: # vi /bin/shutdown /usr/sbin/shutdown -y -g0 -i5 把别的用户logout,试着用shutdown用户登录。输入完用户名和口令后,系统就开始关机。 |
最后大鱼儿和一个同事建议我使用sudo。尝试下总归是好的,去sunfreeware.com下载相关的包,上传到服务器。
|
# gunzip libgcc-3.4.6-sol10-sparc-local.gz |
一切准备就绪。然后用shdUser登陆。
|
$ vi .profile |
更多sudo信息可以参考Sudo Main Page。
Oracle本身的备份策略很多,这里只说说简单的exp命令备份在双机互为主备的方案中shell怎么做。
由于互为主备,平时AB机各自运行自己的实例,当然发生故障后有双机软件去实现自动切换。这样就导致了存储上挂接的同一个lum并不会同时出现两台主机上。那么传统的exp备份脚本就无法正常运行。比如常用的exp的shell脚本如下:
| ORACLE_BASE=/export/home/oracle export ORACLE_BASE ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1 export ORACLE_HOME ORACLE_SID=test export ORACLE_SID LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib:/usr/openwin/lib export LD_LIBRARY_PATH NLS_LANG="simplified chinese"_china.zhs16gbk export NLS_LANG ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data export ORA_NLS33 PATH=$PATH:/opt/SUNWspro/bin:/usr/sbin:/opt/bin:$ORACLE_HOME/bin:/usr/ccs/bin export PATH DATE=`date +%Y%m%d` cd /databak gzip test${DATE}.dmp |
如果套用到互为备份的双机中,就有问题,这个shell到底放在A机还是B机呢?还是两台都放?
如果放在其中一台服务器上,假设放在A机上。A机出问题(网络故障或者系统故障),数据库B机自动接管了(这时存储上的lum都会挂接到B机)。A机脚本就无法工作。
如果A、B机都放,依然是问题。存储上的lum是无法同时挂接到两台服务器的。
因此,那就应该考虑,从判断监听是否启动或者判断数据库是否启动入手,通过shell生成一个flag文件,然后去判断这个flag文件大小。修改后的shell如下:
| ORACLE_BASE=/export/home/oracle export ORACLE_BASE ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1 export ORACLE_HOME ORACLE_SID=test export ORACLE_SID LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib:/usr/openwin/lib export LD_LIBRARY_PATH NLS_LANG="simplified chinese"_china.zhs16gbk export NLS_LANG ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data export ORA_NLS33 PATH=$PATH:/opt/SUNWspro/bin:/usr/sbin:/opt/bin:$ORACLE_HOME/bin:/usr/ccs/bin export PATH DATE=`date +%Y%m%d` |
最后,在AB机都放上这个脚本。在crontab中写好执行时间,也不会因为其中一台服务器down掉导致备份无法正常执行。
Oralce做双机一般来说都是高可用的代名词,可以采用各种不同的HA软件来做,这里不具体涉及到HA软件,只是从Oracle本身出发。
常见的方式就是一主一备,这样一般数据库只有一个实例,这样的双机方案很多。而互为主备,就只能采用双实例方式,也就是说A机日常运行实例A,B机运行实例B。当故障发生时,在另外一台机器上启动数据库。
实施的时候很简单。在方案设计时,必须要将A、B机的实例A和实例B全部设计在存储上。
1、在A机和B机上安装好数据库软件,仅软件本身,不创建数据库和监听。注意确保2台机器上oracle用户和dba组 id相同。
2、在A机或者B机上创建实例,比如这里A机创建实例A和数据库,之后再创建实例B和数据库。然后建立监听。
3、将A机的$ORACLE_HOME下,dbs下spfile,orapwfile等copy到B机,将 A机的 network/admin目录下listener.ora和tnsnames.ora文件也copy到B机。并修改listener.ora文件中host参数所指IP。将A机的$ORACLE_BASE目录下的admin目录下所有文件(包括<SID>中的bdump、udump、cdump等dump文件目录),全部copy到B机。注意:这里listener.ora对于互为主备的方案必须要是两个监听名,比如LISTENER_A和LISTENER_B。举例如下(粗体处请特别注意):
|
# listener.ora Network Configuration File: /export/home/oracle/product/10.2.0/db_1/network/admin/listener.ora LISTENER_A = LISTENER_B = SID_LIST_LISTENER_A = SID_LIST_LISTENER_B = |
4、尝试在B机上启动实例B监听和数据库。如果有问题,再按照出错信息找原因(这句话有点白,实际上就是如果前面3步正确,那这里应该不会有问题。如果第三点listener.ora粗体处KEY一致,可能会在启动监听时报错:TNS-01106 Listener using listener name string has already been started)。
5、手工测试:尝试在A机上启动两个实例数据库,尝试在B机上启动两个实例的数据库。
6、HA软件测试:如果没问题,剩下的工作就交给HA软件了。只是在故障发生后,不管什么HA软件都需要手动切换回去。注意:这里和单机的Oracle区别在于不需要再去建立服务器重启后Oracle的重启脚本之类的,一切都应该是HA软件来完成,否则可能导致HA软件无法接管并启动数据库。
回过头来,觉得真的很简单。但是实际在我实施的过程中遇到了些问题,都是因为上面的第三点,如果有文件拷贝不完整,就无法启动B机的数据库。还有,安装的时候一定要保持头脑清醒,我都做到最后一步了,发现昨晚1点在A机上创建的实例A没有放在存储上,简单的只能删除了重建(当然也有办法改,不过相对删除重建要麻烦点)。最后,这里不得不说到Unix系统,不像Windows一样有注册表的概念,才会有这样如此简单的办法。以上写的都相对简单。
1、solaris10 + oracle10.2.0.4 rac
2、连接时出现ORA-12545:增加两个节点的LOCAL_LISTENER设置。用sys帐号登录后分别在两个节点执行:
ALTER SYSTEM SET LOCAL_LISTENER = ‘(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.7)(PORT = 1521))’ SID = ‘testdb1′;
ALTER SYSTEM SET LOCAL_LISTENER = ‘(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.8)(PORT = 1521))’ SID = ‘testdb2′;
3、客户端tnsname.ora
testDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.7)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.8)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = swpudb)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
4、导入两个应用的数据做测试后,
5、问题:就是在node1使用ssh连接时,键入命令有时停顿很严重,但是服务器负载很低。而且应用程序连接是也非常缓慢,这种情况一天内不间断发生。尝试修改应用连接的VIP地址,将两个node的VIP互换,发现应用程序可正常连接,响应速度正常。说明node1有问题,但是至今无法确认到底是什么问题。无比头疼。
6、在node1中查看alter日志:
-bash-3.00$ tail -200 /export/home/oracle/admin/swpudb/bdump/alert_testdb1.log | grep ORA
Starting ORACLE instance (normal)
Starting up ORACLE RDBMS Version: 10.2.0.4.0.
WARNING: inbound connection timed out (ORA-3136)
WARNING: inbound connection timed out (ORA-3136)
在node2中查看alter日志:
-bash-3.00$ tail -200 /export/home/oracle/admin/swpudb/bdump/alert_testdb2.log | grep ORA
Starting ORACLE instance (normal)
Starting up ORACLE RDBMS Version: 10.2.0.4.0.
google出的一个文档:http://www.dbasky.net/archives/2009/05/oracle10gora-3136.html,按照文档所说在两个节点上都增加响应配置。
$ lsnrctl
LSNRCTL> show inbound_connect_timeout
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hpcmdb2.transgd)(PORT=1521)))
LISTENER parameter "inbound_connect_timeout" set to 60
The command completed successfully
LSNRCTL> set inbound_connect_timeout 0
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hpcmdb2.transgd)(PORT=1521)))
LISTENER parameter "inbound_connect_timeout" set to 0
The command completed successfully
LSNRCTL> show inbound_connect_timeout
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hpcmdb2.transgd)(PORT=1521)))
LISTENER parameter "inbound_connect_timeout" set to 0
The command completed successfully
LSNRCTL> exit
7、节点1依然不正常……
multibox肯定是个好东西。但是如果使用时忽略如下第二行,页面就会报错。
这个错误不影响浏览,在FireFox中从错误控制台可以看到错误-this.contentToLoad.desc.injectInside is not a function,IE则双击状态栏后看到“对象不支持此属性或方法”。仔细查看了multibox.js文件,发现作者在code时就要求每个展示对象都需要一个描述。如果没有这个描述就会这样。尝试更改整个代码结构,无功而返。给作者写了封mail,希望下个版本修正吧。其实也不算多大的错误。整个中文站点信息中都没有搜索到类似的问题信息,遂记录下来备查。
另外http://www.open-open.com/也是个很好的资源站,推荐一下。
先说说高校内web应用的现状。
首先,学校官方主页肯定是由类似网管中心等部门制作,校内其他部门负责内容的更新。从技术层面来说这应该是学校技术力量的最强面,因此不管从应用的设计和编码,可能都高于其他校内二级部门网站。而校内其他二级部门网站往往都是各部门自己制作,可能会有熟悉的老师来设计。也许多数都是找勤工助学的学生制作占多数。当然上面所说到的只是一个基本情况,也有例外(不过已经是过去时了)。
那么用Sqiud这样的软件建一个cache-pool显得没有必要。因为可能只有学校的主页才生成了静态页面,而其他二级部门网站可能都是动态的脚本。cache-pool也就仅仅只能缓存css、图片和js了。再加上访问量也不大,兴许就一个普通的PC就能支持。退一步来讲,就算整个学校统一规划,将学校的所有部门网站全盘考虑,制作成一个大型的管理平台,各个部门各有特色的页面,那就很有可能都会生成静态的页面。但是对于各部门来讲也许不满意,因为需求不停的有变化,或者说审美有变化,那么维护和制作这样一个平台的部门就有的忙了。就算这样实现之后,建立cache-pool?还是显得没有必要。毕竟对于高校的站点,对内对外来说一天都不可能超过500w的ipview(这个不好估计,随便写了一个)。记得2002年那会儿,电子科技大学好像就做了一个这样的平台,但是各部门都是统一的样式,只是配色不同。刚才翻看了一下,已经不存在了,又是各个部门百花齐放的状态。
上面仅仅说到了高校对外的应用。那么对内的应用呢?比如OA、教务系统、财务系统、人事系统呢?更没必要。这些往往都是需要先登录方能使用。对于这样的应用cache-pool更是无用无之地。但是随着数字化校园的推动。各式各样的系统都会在统一的数据中心上做一个数据抽取。也就是说数据中心将各个系统可以公开查询的数据抽取出来,生成相应的页面,供校内师生员工查看。倘若这样的页面是静态的,倘若对于这样的数据展示页面有很大的访问量,那么cache-pool就有存在的理由了。如果学校对硬件投入不是很大,那么用一台普通的pcserver架一个cache-pool,如果按照Squid所说每G磁盘空间需要32M内存来算,16G的内存将会缓存512G的数据。足够满足校内大数据量访问的要求。关键是需要通过实际的测试来证明是否需要这样的cache-pool。
写了这么多,感觉都是废话,不过既然写了,就算整理自己的思路吧。
清明期间看到大鱼儿写的Nginx并发逼近1万大关,想想学校的教务系统的web端,应该也可以用到Nginx。因为之前用Apache加载resin来做的负载均衡,但是偶尔会出现登录后500的错误,百思不得其解,但是只要刷新一下就好了。所以后来放弃了用Apache加载resin做负载均衡。所以看了大鱼儿的blog就跃跃欲试。
1、服务器是sun4v系列的,查看了官方的说明可以支持,直接下载了稳定版。
2、由于自己只是做一个负载均衡,不需要其他一些模块,所以连PCRE我也放弃了。
3、需要gcc或者其他来编译,操作系统没装,我就去down了个gcc回来。
准备工作就绪,把包传到服务器上去。开工。
| # gunzip gcc-3.4.6-sol10-sparc-local.gz # pkgadd -d ./gcc-3.4.6-sol10-sparc-local # gunzip libiconv-1.11-sol10-sparc-local.gz # pkgadd -d ./libiconv-1.11-sol10-sparc-local # PATH=$PATH:/opt/gnome/bin:/usr/local/bin:/opt/netscape:/usr/ccs/bin # exprot PATH # gzip -d nginx-0.6.36.tar.gz # tar xvf nginx-0.6.36.tar # ./configure –without-http_rewrite_module –user=webadmin –group=webadmin –with-http_stub_status_module checking for OS + SunOS 5.10 sun4v checking for C compiler … found + using GNU C compiler + gcc version: 3.4.6 checking for gcc -pipe switch … found checking for gcc variadic macros … found checking for C99 variadic macros … found checking for unistd.h … found checking for inttypes.h … found checking for limits.h … found checking for sys/filio.h … found checking for crypt.h … found checking for SunOS specific features checking for sendfilev() … found checking for event ports … found checking for poll() … found checking for /dev/poll … found checking for kqueue … not found checking for crypt() … found checking for zlib library … found checking for int size … 4 bytes checking for long size … 4 bytes checking for long long size … 8 bytes checking for void * size … 4 bytes checking for uint64_t … found checking for sig_atomic_t … found checking for sig_atomic_t size … 4 bytes checking for socklen_t … found checking for in_addr_t … found checking for in_port_t … found checking for rlim_t … found checking for uintptr_t … uintptr_t found checking for system endianess … big endianess checking for size_t size … 4 bytes checking for off_t size … 8 bytes checking for time_t size … 4 bytes checking for setproctitle() … not found checking for pread() … found checking for pwrite() … found checking for strerror_r() … found checking for gnu style strerror_r() … found but is not working checking for localtime_r() … found checking for posix_memalign() … not found checking for memalign() … found checking for sched_yield() … found checking for mmap(MAP_ANON|MAP_SHARED) … found checking for mmap("/dev/zero", MAP_SHARED) … found checking for System V shared memory … found checking for struct msghdr.msg_control … not found checking for ioctl(FIONBIO) … found checking for struct tm.tm_gmtoff … not found Configuration summary nginx path prefix: "/usr/local/nginx" make -f objs/Makefile gcc -c -mcpu=v9 -O -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Wno-unused-function -Wunused-variable -Wunused-value -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \ ………省略………. # makeinstall |
要让人笑掉大牙的地方就在make那里,我几乎耗费了整整一天的时间来找原因。我make的时候看到有error字样就以为是错误,屏幕显示问题成了-W在上一行的最后部分,error在第二行开头。我就以为是错误,然后到邮件列表啊什么的里面去海找。