JJH-NoteBook

笔记本


  • 首页

  • 归档

Tomcat

发表于 2018-04-25

Tomcat


一直用着tomcat作为应用服务器,但是对tomcat的原理一直停留在会用而已的阶段,今天仔细学习了下,看了网上大量的文章,把自己不懂的一些概念拿出来列出来,其中有各位大神的精炼解析,也添加了一些自己平时遇到的问题及解决方法


Tomcat处理资源

Tomcat访问所有的资源,都是用Servlet来实现的。所以Tomcat又叫Servlet容器嘛,什么都交给Servlet来处理。

在Tomcat看来,资源分3种:

  1. 静态资源,如css,html,js,jpg,png等。交由DefaultServlet类处理
  2. Servlet,交由InvokerServlet类处理
  3. JSP,交由JspServlet类来处理

那么什么时候调用哪个Servlet呢?

有一个类叫做org.apache.tomcat.util.http.mapper.Mapper,它一共进行了7个大的规则判断,第7个,就是判断是否是该用DefaultServlet。
简单地说:先看是不是servlet,然后看是不是jsp,如果都不是,那么就是你DefaultServlet的活儿了。
到了DefaultServlet之后,就是一个普通的HttpServlet了,doPost方法会交由doGet处理,doGet又交由一个叫做 serveResource的方法处理,在serveResource方法里又瞎搞八搞了许多事情,最后在一个叫做copy()方法里,把静态资源对应的输入流读取出来,扔到了输出流里,这样你的浏览器就看到数据了。


Tomcat调优

Tomcat的优化分成两块:

  1. Tomcat启动命令行中的优化参数即JVM优化
  2. Tomcat容器自身参数的优化(这块很像ApacheHttp Server)

1 启动行参数优化

启动行参数的优化其实就是JVM的调优,可以参考网上JVM调优的一些方法(这里给出一个链接),Tomcat 的启动参数位于tomcat的安装目录\bin目录下的catalina.sh文件,在最开始注释文字的最后一段也就是真正有效的shell命令开始的那里加入需要添加的参数即可,需要注意的一点是在生产环境需要添加一个tomcat特有的参数:-server。这个参数告诉mysql这是在真正生产环境,它会自动做一些优化的。

2 容器优化
前面我们对Tomcat启动时的命令进行了优化,增加了系统的JVM可使用数、垃圾回收效率与线程阻塞情况、增加了系统响应效率等还有一个很重要的指标,我们没有去做优化,就是吞吐量。
打开tomcat安装目录\conf\server.xml文件,定位到这一行:

1
<connector port="8080" protocol="HTTP/1.1" >

这一行就是我们的tomcat容器性能参数设置的地方,它一般都会有一个默认值,这些默认值是远远不够我们的使用的,我们来看经过更改后的这一段的配置(配置的详细含义):

1
2
3
4
5
6
7
8
9
<connector port="8080" protocol="HTTP/1.1" 
URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
redirectPort="8443"
/>

3 Tomcat的运行模式
bio: (blocking I/O),阻塞式I/O操作,一般而言,表示Tomcat使用的是传统的Java I/O操作。bio模式是三种运行模式中性能最低的一种。
nio: nio(new I/O),是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即Java.nio包及其子包)。java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性能。关于nio与bio在tomcat上的差别可以参考这个简书:NIO只是优化了网络IO的读写,如果系统的瓶颈不在这里,比如每次读取的字节说都是500b,那么BIO和NIO在性能上没有区别。(个人感觉与socket的nio一样,并发小于1000时,区别不大,而并发很多的时候,更多的是使用nginx)
apr: (Apache Portable Runtime/Apache可移植运行时),是Apache HTTP服务器的支持库。可以简单地理解为Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat对静态文件的处理性能。 Tomcat apr也是在Tomcat上运行高并发应用的首选模式。
修改运行模式为NIO模式:修改server.xml里的Connector节点,修改protocol为org.apache.coyote.http11.Http11NioProtocol

注:通过对tomcat几个版本的测试,tomcat7默认启动是bio模式,需要优化;tomcat8及8以上默认是nio模式,无需改变运行模式,如果是windows版本的话,包里面还默认携带一个tcnative-1.dll,默认就是在Tomcat apr模式下运行。


Tomcat版本

之前在工作中遇到了tomcat 的启动问题,然后同事提到说tomcat的linux版本和windows版本可以互用的,于是去下载官网的源文件,通过对比发现,Linux版本的Tomcat和Windows相比,确实是可以互换的,windows版本包含全部linux版本的文件,只是在windows的版本中多加了2个.exe文件和一个tcnative-1.dll文件。查阅了下之类发现tcnative-1.dll是用于tomcat的apr模式使用。


编码设置

之前遇到过tomcat的编码是UTF8的,但是怎么改都改不成GBK,然后查了很多资料,自己也找了很多地方,发现Tomcat 的编码通常在两个地方可以配置,一是conf/server.xml,二是bin/catalina.sh

conf/server.xml

1
2
3
<Connector executor="tomcatThreadPool"
port="8088" protocol="HTTP/1.1"
redirectPort="8443" URIEncoding="GBK"/>

bin/catalina.sh

1
JAVA_OPTS="${JAVA_OPTS} -Dfile.encoding=GBK"

参考:
Tomcat处理资源
Tomcat调优



MyBatis的执行流程

发表于 2018-04-24

MyBatis的执行流程


  1. mybatis 配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。

  2. mybatis通过读取配置文件信息(全局配置文件和映射文件),生成Configuration对象,然后根据Configuration构造出SqlSessionFactory,即会话工厂。

  3. 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。

  4. SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。MyBatis封装了对数据库的访问,把对数据库的会话和事务控制放到了SqlSession对象中

  5. Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。

    >**Executor的功能和作用**
     > 根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用;
    > 为查询创建缓存,以提高性能;
    > 创建JDBC的Statement连接对象,传递给StatementHandler对象,返回List查询结果;
    

参考:https://blog.csdn.net/qq_32166627/article/details/70741729


Mybatis与JPA比较

发表于 2018-04-16

Mybatis与JPA比较


Mybatis

  • 需要在spring-boot的主类添加@MapperScan(“com.example.demo.dao”)
  • 需要添加Mapper(Dao)接口,自定义所有的Dao方法以及使用注解或者xml添加对应方法的sql实现。
  • 没有自动建表,需要手动建表。
  • 配置application.properties连接数据库属性。

JPA

  • 需要在pojo类添加注解@Entity,pojo类对应的每个属性需要添加@Id或者@Column。
  • 添加Repository(Dao)接口,需要实现JpaRepository接口,可以不写方法声明。
  • 配置application.properties连接数据库属性。
  • 可通过配置spring.jpa.properties.hibernate.hbm2ddl.auto=update属性实现自动建表。

总结:都需要添加Dao类,Mybatis的Dao类需要实现具体sql(注解或者xml),JPA不需要。对于pojo类的侵入性而言,Mybatis无需更改pojo类的任何地方,而JPA需要添加注解实现映射。


分布式系统中的幂等性

发表于 2018-04-13

分布式系统中的幂等性

现如今我们的系统大多拆分为分布式SOA(面向服务的架构),或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者restful,既然是通信,那么就有可能再服务器处理完毕后返回结果的时候挂掉,这个时候用户端发现很久没有反应,那么就会多次点击按钮,这样请求有多次,那么处理数据的结果是否要统一呢?那是肯定的!尤其再支付场景。


幂等性

就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品使用约支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条

那么如何设计接口才能做到幂等呢?

方法一:单次支付请求
也就是直接支付了,不需要额外的数据库操作了,这个时候发起异步请求创建一个唯一的ticketId,就是门票,这张门票只能使用一次就作废,具体步骤如下:

  1. 异步请求获取门票
  2. 调用支付,传入门票
  3. 根据门票ID查询此次操作是否存在,如果存在则表示该操作已经执行过,直接返回结果;如果不存在,支付扣款,保存结果
  4. 返回结果到客户端

如果步骤4通信失败,用户再次发起请求,那么最终结果还是一样的

方法二:分布式环境下各个服务相互调用
举例支付系统,我们支付的时候先要扣款,然后更新订单,这个地方就涉及到了订单服务以及支付服务了。
用户调用支付,扣款成功后,更新对应订单状态,然后再保存流水。
而在这个地方就没必要使用门票ticketId了,因为会比较显的麻烦(支付状态:未支付,已支付)步骤:

  1. 查询订单支付状态
  2. 如果已经支付,直接返回结果
  3. 如果未支付,则支付扣款并且保存流水
  4. 返回支付结果

如果步骤4通信失败,用户再次发起请求,那么最终结果还是一样的

注:幂等,也可以称之为冲正,保证客户端与服务端的交易一致性,避免多次扣款。

参考:https://www.cnblogs.com/leechenxiang/p/6626629.html

Vue的双向数据绑定原理

发表于 2018-04-09

Vue的双向数据绑定原理

vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。


具体步骤:

  1. 需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化

  2. compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

  3. Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:

    > 在自身实例化时往属性订阅器(dep)里面添加自己
    > 自身必须有一个update()方法
    > 待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
    
  4. MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。


Apache HTTP Server

发表于 2018-03-21

Apache HTTP Server 这个项目的目标是提供一个安全,高效和可扩展的服务器,提供与当前HTTP标准同步的HTTP服务。


和Tomcat 之区别

  ► Apache Http Server是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展。
► Apache和Tomcat都可以做为独立的web服务器来运行,但是Apache不能解释java程序(jsp,serverlet)。
► Apache是普通服务器,本身只支持html即普通网页。不过可以通过插件支持php,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)
► 两者都是一种容器,只不过发布的东西不同:Apache是html容器,功能像IIS一样;Tomcat是jsp/servlet容器,用于发布jsp及java的,类似的有IBM的webshere、EBA的Weblogic,sun的JRun等等。
► Apache和Tomcat是独立的,在通一台服务器上可以集成。 
► Apache只支持静态网页,但像asp,php,cgi,jsp等动态网页就需要Tomcat来处理。 

示例:Apache是一辆卡车,上面可以装一些东西如html等。但是不能装水,要装水必须要有容器(桶),Tomcat就是一个桶(装像Java这样的水),而这个桶也可以不放在卡车上。

Apache Http Server与Tomcat实现负载均衡

为什么要让http server与Tomcat之间进行连接:事实上Tomcat本身已经提供了HTTP服务,该服务默认的端口是8080,装好tomcat后通过8080端口可以直接使用Tomcat所运行的应用程序,你也可以将该端口改为80。既然Tomcat本身已经可以提供这样的服务,我们为什么还要引入Apache或者其他的一些专门的HTTP服务器呢?原因有下面几个:

1. 提升对静态文件的处理性能。
2. 利用Web服务器来做负载均衡以及容错。
3. 无缝的升级应用程序。

这三点对一个web网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个Tomcat宕机或者是升级程序导致用户访问不了,而能完成这几个功能的、最好的HTTP服务器也就只有apache的http server了,它跟tomcat的结合是最紧密和可靠的。


Hexo

发表于 2018-03-21

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

CSDN的md编辑器编辑:http://write.blog.csdn.net/mdeditor
发布步骤:
hexo clean
hexo g
hexo d

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

xqlsrjjjh

7 日志
© 2018 xqlsrjjjh
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4