0%

tomcat 7+依赖于SecureRandom为其session id及其他事项生成随机数,但由于JRE等各方面的因素,可能会导致tomcat启动特别缓慢。
catalina.out里会有类似如下提示

1
2
3
...
INFO: Creation of SecureRandom instance for session ID generation using \[SHA1PRNG\] took \[586,623\] milliseconds.
...

通过配置JRE使用非阻塞的熵源,可以解决此问题,但因随机性下降会降低系统安全性。

为JRE添加如下属性

1
-Djava.security.egd=file:/dev/./urandom

比如可以在/etc/default/tomcat8中的添加:

1
JAVA_OPTS="-Djava.awt.headless=true -Xmx1280m -XX:+UseConcMarkSweepGC -Djava.security.egd=file:/dev/./urandom"

References:
[1]How do I make Tomcat startup faster?

===
[erq]

应用程序启动时有如下错误提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
ERROR \[localhost-startStop-1\] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'atomikosUserTransaction' defined in ServletContext resource \[/WEB-INF/conf/spring-servlet.xml.bak\]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'transactionTimeout' threw exception; nested exception is com.atomikos.icatch.SysException: Error in init(): /var/lib/tomcat8/./tm.out.lck
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java: 1506)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:629)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:677)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:548)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:919)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1703)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'transactionTimeout' threw exception; nested exception is com.atomikos.icatch.SysException: Error in init(): /var/lib/tomcat8/./tm.out.lck
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:121)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java: 1502)
... 33 more

这是因为默认情况下,atomikos要在/var/lib/tomcat8目录下生成其日志和锁文件,而/var/lib/tomcat8文件夹的所有者和组都是root,无法写入,所以初始化失败。

解决方法有二,最简单粗暴的就是将/var/lib/tomcat8目录的所有者和组都更改为tomcat8.

另一个方法是classpath中添加atomikos配置文件,将其输出文件目录配置到tomcat8有权限写入的目录中,比如/var/log/tomcat8

1
2
3
4
5
6
7
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.log_base_name = jdbc
com.atomikos.icatch.log_base_dir = /var/log/tomcat8 # 日志文件输出目录
com.atomikos.icatch.output_dir = /var/log/tomcat8 # 文件输出目录
com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm
com.atomikos.icatch.serializable_logging=false
com.atomikos.icatch.max_timeout=2000000

===
[erq]

几个意思相近又有区别的词语:
crew 全体船员; 全体乘务员;全体工作人员
staff 全体职员; 全体管理人员;
faculty 全体教员
crowd 一群,人群

查看oracle job的运行状态,可以查询这几张系统视图ALL_SCHEDULER_JOB_LOG/DBA_SCHEDULER_JOB_LOG和dba_scheduler_job_run_details

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python3

import tkinter

#from tkinter import *

tk = tkinter
root = tk.Tk()
label = tk.Label(root, text="hello tkinter")
label.pack()
root.mainloop()

===
[erq]

The keyword SNAPSHOT is supported in place of MATERIALIZED VIEW for backward compatibility.
也就是以前叫“快照”,现在叫“物化视图”了。

keyspace创建以后,仍然可以更改其复制因子,也就是keyspace中数据的复制份数是可以动态修改的。

cassandra集群的系统keyspace system_auth默认的replication factor是1,也就是其实是没有冗余的。如果这唯一的节点挂掉,就无法再登录到集群了。
因此官方文档推荐将其复制因子设置为每个数据中心的每一个节点。也就是将其复制到集群中的每一个节点上。

查看system_auth的复制因子

1
2
3
cqlsh> DESC KEYSPACE system_auth
CREATE KEYSPACE system_auth WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true;
...

果然replication factor只有1,修改之:

1
cqlsh> ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1':2,'dc2':2};

durable_writes参数用于设置写数据时是否写入commit log,如果设置为false,则写请求不会写commit log,会有丢失数据的风险。
此参数默认为true,即要写commit log,生产系统应该将该参数设置为true。

References:
[1]CREATE KEYSPACE

===
[erq]

xterm终端窗口默认标题都是一样的。经常开很多终端窗口,虽然已经设置了命令行提示符,但如果标题栏也能反应出xterm的当前状态就更好了。

更改标题栏

可以使用xterm的转义序列更改窗口的title

  • ESC]0;stringBEL — Set icon name and window title to string
    设置图标化名字(窗口最小化时)和窗口标题
  • ESC]1;stringBEL — Set icon name to string
    设置图标化名字
  • ESC]2;stringBEL — Set window title to string
    设置窗口标题

where ESC is the escape character (\033), and BEL is the bell character (\007)
此处,ESC是转义字符\033,BEL是bell字符\007

因此在.bashrc中添加如下行,让xterm标题栏显示当前的主机名和用户名以及当前路径信息:

1
PROMPT_COMMAND='echo -ne "\\033\]0;${USER}@${HOSTNAME}\[\`basename ${PWD}\`\]\\007"'

ssh登录时更改标题栏

ssh登录时,xterm窗口应该显示当前所在的远程主机和在远程主机上的当前用户以及路径信息,只要在远程主机的bashrc文件中包含同样的行就可以了。

终端vim标题栏

在终端下使用vim时,默认会修改xterm的标题栏,但是没有主机和用户信息,在~/.vimrc中添加如下:

1
2
let &titlestring=$USER."@".hostname().": %t%M(%F)"
set title

更多符号的含义请

1
2
:help titlestring
:help statusline

References:
[1]Automatically set screen title

===
[erq]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# bash
set -o vi
PS1='${debian_chroot:+($debian_chroot)}\\\[\\033\[00;31m\\\]\\u@\\h\\\[\\033\[00m\\\]:\\\[\\033\[00;33m\\\]\\w\\\[\\033\[00m\\\]\\$ \\\[\\033\[00;32m\\\]'

# bash history
export HISTCONTROL=ignoredups
shopt -s histappend

export PATH=$HOME/bin:/sbin:/usr/sbin:/usr/local/sbin:/opt/bin:$PATH

# xterm
if \[ "$TERM" == "xterm" \]; then
export TERM=xterm-256color
fi

# mac os x
if \[ \`uname\` == "Darwin" \]; then
alias ll='ls -lh grep ^total && ls -lh grep ^d && ls -lh grep -v ^d grep -v ^total'
fi

# freebsd
if \[ \`uname\` == "FreeBSD" \]; then
# gnuls
alias ls='gnuls --color=auto --show-control-chars'
fi


# linux
if \[ \`uname\` == "Linux" \]; then
alias ll='ls -lh --group-directories-first'
alias update='sudo apt-get update && sudo apt-get dist-upgrade -y && sudo apt-get autoremove -y'
fi

# general
alias la='ls -a'
alias ccd='clear;cd'
alias :q='exit'

# mail
export MAIL=$HOME/Maildir

#oracle
alias sqlplus='rlwrap sqlplus'
alias rman='rlwrap rman'

#export ORACLE_SID=
#export ORACLE_BASE=/u01/app/oracle
#export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1
#export PATH=$ORACLE_HOME/bin:$PATH
#export TNS_ADMIN=$ORACLE_HOME/network/admin
#export SQLPATH=$ORACLE_BASE/scripts

===
[erq]