1.Linux下如何查看/监控JVM内存?(快的)
本地(带图形环境):jvisualvm 连接远程JVM
线上(无图形环境):看总内存用top,看详细信息用jmap dump出来分析
2.经常看到url中很长的一串请求参数,为什么不采用post方式?
GET一般用于获取/查询 资源信息,而POST一般用于更新 资源信息。
查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:
1
|
/test/demo_form.asp?name1=value1&name2=value2
|
POST 方法
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
1
2
3
|
POST /test/demo_form.asp HTTP/
1.1
Host: w3schools.com
name1=value1&name2=value2
|
3.遇到OOM(Out of Memory)如何处理?
OMM主要三类:
permgen OOM , 由于加载的类太多,或者反射的类太多
heap OOM, 因为一些无用对象没有及时释放造成的,检查代码加上 heap dump 去分析吧
stack overflow ,由于调用层数,或者递归深度太大造成的
常见的错误提示:
1
2
3
4
5
|
tomcat:java.lang.OutOfMemoryError: PermGen space
tomcat:java.lang.OutOfMemoryError: Java heap space
weblogic:Root cause of ServletException java.lang.OutOfMemoryError
resin:java.lang.OutOfMemoryError
java:java.lang.
|
导致OutOfMemoryError异常的常见原因有以下几种:
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
代码中存在死循环或循环产生过多重复的对象实体;
使用的第三方软件中的BUG;
启动参数内存值设定的过小;
解决方法:
1.应用服务器提示错误的解决:
把启动参数内存值设置足够大。
2.Java代码导致错误的解决:
重点排查以下几点:
1)检查代码中是否有死循环或递归调用。
2)检查是否有大循环重复产生新对象实体。
3)检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
4 )检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
1
2
3
4
5
6
7
8
9
10
11
12
|
tomcat中java.lang.OutOfMemoryError: Java heap space异常处理
一、Heap size
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,
其初始空间(即-Xms)是物理内存的
1
/
64
,最大空间(-Xmx)是物理内存的
1
/
4
。可以利用JVM提供的-Xmn -Xms -Xmx等选项可
进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
提示:在JVM中如果
98
%的时间是用于GC且可用的Heap size 不足
2
%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的
80
%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为
1
/
4
的-Xmx值。
二、解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.sh
在“echo
"Using CATALINA_BASE: $CATALINA_BASE"
”上面加入以下行:
JAVA_OPTS=
"-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
tomcat中java.lang.OutOfMemoryError: PermGen space异常处理
一、PermGen space
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,
这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,
它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对
PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误,
这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小
超过了jvm默认的大小(4M)那么就会产生此错误信息了。
解决方法: 手动设置MaxPermSize大小
修改TOMCAT_HOME/bin/catalina.sh
在“echo
"Using CATALINA_BASE: $CATALINA_BASE"
”上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
weblogic中java.lang.OutOfMemoryError异常处理
错误提示:
"Root cause of ervletException java.lang.OutOfMemoryError"
解决办法:
调整bea/weblogic/common中CommEnv中参数
:sun
if
"%PRODUCTION_MODE%"
==
"true"
goto
sun_prod_mode
set JAVA_VM=-client
set MEM_ARGS=-Xms256m -Xmx512m -XX:MaxPermSize=256m
set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none
goto
continue
:sun_prod_mode
set JAVA_VM=-server
set MEM_ARGS=-Xms256m -Xmx512m -XX:MaxPermSize=256m
goto
continue
|
4.数据库中内连接与外连接的区别?
SQL 的连接(JOIN)语句将数据库中的两个或多个表组合起来.
由"连接"生成的集合, 可以被保存为表, 或者当成表来使用. JOIN 语句的含义是把两张表的属性通过它们的值组合在一起. 基于 ANSI 标准的 SQL 列出了五种 JOIN 方式: 内连接(INNER), 全外连接(FULL OUTER), 左外连接(LEFT OUTER), 右外连接(RIGHT OUTER)和交叉连接(CROSS). 在特定的情况下, 一张表(基本表, 视图, 或连接表)可以和自身进行连接, 成为自连接(self-join).
内连接(inner join),外连接(outer join),
内连接又包括等值连接,非等值连接,自连接;而外连接又分为左连接和右连接。其中默认的是内连接的等值连接。
外连接的三种情况大概就是取A、B的并集,或者A或者B的完全集。交叉连接是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。交叉连接产生的数据集较大,影响性能,尤其是表很大的时候。
5.HTTP 不同状态码的意义。
消息 1字头:
一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送 1xx 响应。
成功 2字头:
这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
重定向 3字头:
这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。
当且仅当后续的请求所使用的方法是 GET 或者 HEAD 时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A->A,或者A->B->C->A),因为这会导致服务器和客户端大量不必要的资源消耗。按照 HTTP/1.0 版规范的建议,浏览器不应自动访问超过5次的重定向。
请求错误 4字头:
这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个 HEAD 请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
如果错误发生时客户端正在传送数据,那么使用TCP的服务器实现应当仔细确保在关闭客户端与服务器之间的连接之前,客户端已经收到了包含错误信息的数据包。如果客户端在收到错误信息后继续向服务器发送数据,服务器的TCP栈将向客户端发送一个重置数据包,以清除该客户端所有还未识别的输入缓冲,以免这些数据被服务器上的应用程序读取并干扰后者。
服务器错误 5字头:
这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD 请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。
6.高并发,执行耗时短的任务,还有低并发,执行耗时长的任务,各自选取什么样的线程池会比较合理?为什么?如果业务场景是高并发,且任务耗时长时,有什么解决思路?
线程池的关键点是:
1、尽量减少线程切换和管理的开支;
2、最大化利用cpu。
对于1,要求线程数尽量少,这样可以减少线程切换和管理的开支;
对于2,要求尽量多的线程,以保证CPU资源最大化的利用。
所以对于任务耗时短的情况,要求线程尽量少,如果线程太多,有可能出现线程切换和管理的时间,大于任务执行的时间,那效率就低了;
对于耗时长的任务,要分是cpu任务,还是io等类型的任务。如果是cpu类型的任务,线程数不宜太多;但是如果是io类型的任务,线程多一些更好,可以更充分利用cpu。
所以:
高并发,低耗时的情况:建议少线程,只要满足并发即可;例如并发100,线程池可能设置为10就可以
低并发,高耗时的情况:建议多线程,保证有空闲线程,接受新的任务;例如并发10,线程池可能就要设置为20;
高并发高耗时:
1要分析任务类型,
2增加排队,
3加大线程数
7.AIO 和 NIO 有什么区别?就不讨论最早的BIO了。
Java NIO :同步非阻塞,JVM实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
Java AIO :异步非阻塞,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如HTTP服务器等,充分调用OS参与并发操作,JDK7开始支持
简而言之在 Linux 下 NIO 是 JVM内部进行事件的轮训后捕获(可以通过参数打开 nio epoll 来提高新能) ,而 AIO 则是使用 epoll 由操作系统来触发事件.
如果把内核比作快递,NIO就是你要自己时不时到官网查下快递是否已经到了你所在城市,然后自己去取快递;AIO就是快递员送货上门了。
8.如何处理大量并发用户访问网页,并且如何跟踪每个用户?
前台页面:静态化页面资源
分层设计:使用多层缓存
数据库优化,读写分离:配置多台读库
使用NOSQL和搜索引擎:为特定的检索服务配置专门的索引或者搜索引擎,减轻数据库压力
服务器集群改善并发处理能力:配置多台服务器集群,通过负载均衡,将来自用户浏览器的访问请求分发到应用服务器集群中的任何一台服务器上。
反向代理和CDN加速网站响应:可以让用户从距离自己最近的服务器获得请求的资源,尽早返回数据给用户,一方面加快用户访问速度,另一方面也减轻后端服务器的负载压力。
业务拆分:使用消息队列分发请求
9.如果有10万条学生成绩信息,怎么获取成绩最高的那一条数据,怎么获取成绩第三的那一条数据,列举你认为性能最好的方式。
使用 MAX() 函数:
1
|
select
*
from
table
where
table_row
in
(
select
MAX
(table_row)
from
table
)
|
如果支持行号,可以使用ORDER BY,MySQL不支持:
1
2
|
select
*
from
table
where
rownum=1
order
by
table_row
desc
;
|
使用NOT EXISTS:
1
2
|
select
*
from
table
t1
where
not
exists
(
select
1
from
table
where
table_row > t1.table_row)
|
连接MySQL库,主键添加索引情况下查询,MAX()函数方法耗时1.513s,
NOT EXISTS 方法耗时98.655s,数据量877550。
10.序列化的作用,应用场景,除了网络传输。
序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
什么情况下需要序列化
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
11.spring的IOC、AOP的使用场景。
IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩。java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关系业务逻辑本身就可以了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。
这是我对Spring的IOC的体会。DI其实就是IOC的另外一种说法。DI是由Martin Fowler在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
如果对这一核心概念还不理解:这里引用一个叫Bromon的blog上找到的浅显易懂的答案:
IoC与DI
首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。
那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。如果你还不明白的话,我决定放弃。
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
在应用开发中,以应用开发人员的身份设计组件时,往往需要引用和调用其他组件的服务,这种依赖关系如果固化在组件设计中,就会造成依赖关系的僵化和维护难度的增加,这个时候,如果使用IoC容器,把资源获取的方向反转,让IoC容器主动管理这些依赖关系,将这些依赖关系注入到组件中,那么会让这些依赖关系的适配和管理更加灵活。
面向切面编程,AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理、缓存、对象池管理以及日志记录。AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中。AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;而动态代理则在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
代理对象的方法 = 增强处理 + 被代理对象的方法
Spring AOP 则采用运行时生成 AOP 代理类,因此无需使用特定编译器进行处理。由于 Spring AOP 需要在每次运行时生成 AOP 代理,因此性能略差一些。
AOP使用场景
AOP用来封装横切关注点,具体可以在下面的场景中使用
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
12.ajax是否能跨域请求,解决的办法?
可以。
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
13.内部跳转和外部跳转的区别,底层实现原理?
内部跳转的时候实际上是通过服务器端将请求转发到另外的页面或者servlet中,这个时候跳转到的目标页面或者servlet可以获取到请求对象,也可以获取到请求中的属性和参数。而外部跳转的时候实际上是第一次请求后,服务器端向客户端发送了一个指令,让客户端再次请求了一次服务器端,这个时候服务器第二次拿到的request对象已经不是第一次请求的request对象了,所以无法获取到第一次请求里的参数和属性。
内部跳转的url地址栏不会发生变化,外部跳转url则会发生变化。
内部跳转无法跳转到工程以外的jsp或者servlet,外部跳转则可以。
内部跳转实现的方法:
request.getRequestDispatcher("XXX.jsp或者servlet").forward(request, response),
而外部跳转实现的方法:
response.sendRedirect("XXX.jsp或者servlet")。
14.数据库连接池的实现原理,请求怎么样去获取连接,关闭连接时,连接池是销毁连接还是回收连接?
为什么在连接数据库时要使用连接池
连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
数据库连接池的基本原理
数据库连接池的基本思想就是为数据库连接 建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定 连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量和使用情况,为系统开发和测试及性能调 整提供依据。
数据库连接池的工作原理
连接池的工作原理主要由三部分组成,分别为连接池的建立、连接池中连接的使用管理、连接池的关闭。
第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。
第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。
该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。
第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。
连接池关键问题分析
1、并发问题
为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java语言自身提供了对并发管理的支 持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如:
public synchronized Connection getConnection()
2、多数据库服务器和多用户
对于大型的企业级应用,常常需要同时连接不同的数据库(如连接Oracle和Sybase)。如何连接不同的数据库呢?我们采用的策略是:设计 一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址()?用户名()?密 码()等信息。如 tx.url=172.21.15.123:5000/tx_it,tx.user=yang,tx.password=yang321。根据资源文件提 供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连 接池。
对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。
3、事务处理
我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。
在Java语言中,Connection类本身提供了对事务的支持,可以通过设置Connection的AutoCommit属性为 false,然后显式的调用commit或rollback方法来实现。但要高效的进行Connection复用,就必须提供相应的事务支持机制。可采用 每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。
4、连接池的分配与释放
连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内 有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用 就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有 达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果 等待时间超过预定时间timeout,则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状 态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。
5、连接池的配置与维护
连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接 池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很 快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连 接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。
如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
15.tomcat、weblogic、jboss、apache的区别,容器的作用?
Tomcat:应用也算非常广泛的web服务器,支持部分j2ee,免费,出自apache基金组织
JBoss:开源的应用服务器,比较受人喜爱,免费(文档要收费)
Weblogic:应该说算是业界第一的app server,全部支持j2ee1.4, 对于开发者,有免费使用一年的许可证。
Apache:全球应用最广泛的http服务器,免费,出自apache基金组织
Tomcat不支持EJB,只能做jsp和servlet的container,只能做web服务器。
JBoss是实现了EJB容器,同时内嵌Tomcat,处理静态页面Jboss的速度要比较快,可以作应用服务器。
JBoss和WebLogic、WebSphere都含有Jsp和Servlet容器,也就可以做web容器。
JBoss和WebLogic、WebSphere也都包含EJB容器,是完整的J2EE应用服务器 。
16.http和https的区别?
Https是一种基于SSL/TLS的Http协议,所有的http数据都是在SSL/TLS协议封装之上传输的。
Https协议在Http协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。
——>HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
——>HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。
17.对于大表数据的处理?
这个问题比较宽泛,以下几个方面可以考虑:
优化sql查询和索引;
配置缓存,memcached,redis;
主从复制做读写分离;
使用MySQL自带分区表;
数据库切分,包括垂直切分和水平切分。
总之分区分表成本较高,应该是最后才考虑的措施。
更多的可以参考知乎的这个问题:
MySQL 对于千万级的大表要怎么优化?
大表数据的处理应该在系统设计之初就考虑到,未雨绸缪。
18.怎么处理日志问题?有那些可行的方案?
可以使用一些第三方工具将日志统一汇总到一个文件中,
比如这篇文章:
Logstash实践: 分布式系统的日志监控
另外参考:
Twitter是如何构建高性能分布式日志的
19.负载均衡的原理?
负载均衡的原理牵扯到操作系统底层,简单了解。
负载均衡有硬件和软件两种。
硬件层的比较牛逼,将4-7层负载均衡功能做到一个硬件里面,如F5。
目前主流的软件负载均衡分为四层和七层
LVS属于四层负载均衡,工作在tcp/ip协议栈上,通过修改网络包的ip地址和端口来转发, 由于效率比七层高,一般放在架构的前端。
七层的负载均衡有nginx, haproxy, apache等, 工作在应用层,因此可以将HTTP请求等应用数据发送到具体的应用服务器,如将图片请求转发到特定的服务器上,总之可以做到更智能的负载均衡,这些功能在四层负载均衡上不好实现,一般放在架构的后面位置,布置在应用服务器前面。
20.socket 使用的什么协议,tcp协议连接(握手)的过程是什么样的,socket使用要注意哪些问题?
网络由下往上分为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
我们知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层,
三者从本质上来说没有可比性,
socket则是对TCP/IP协议的封装和应用(程序员层面上)。也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,
而HTTP是应用层协议,主要解决如何包装数据。
关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:
“我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容。
如果想要使传输的数据有意义,则必须使用到应用层协议。
应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。
WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上。”
而我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。
通过Socket,我们才能使用TCP/IP协议。实际上,Socket跟TCP/IP协议没有必然的联系。
Socket编程接口在设计的时候,就希望也能适应其他的网络协议。
所以说,Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,
从而形成了我们知道的一些最基本的函数接口,比如create、listen、connect、accept、send、read和write等等。
网络有一段关于socket和TCP/IP协议关系的说法比较容易理解:
“TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。
这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,
TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。”
IP协议的应用和编程接口的知识,也就是刚才说了很多的HTTP和Socket。
HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。
21.https处理的对称加密和非对称加密
1.浏览器将自己支持的一套加密规则发送给网站。
2.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
3.获得网站证书之后浏览器要做以下工作:
a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
c) 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
4.网站接收浏览器发来的数据之后要做以下的操作:
a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
b) 使用密码加密一段握手消息,发送给浏览器。
5.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,
此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。
其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。
由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。
非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。
TLS握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。