省市区数据库

Apache http
server与tomcat同属于apache基金会,两者都可以提供Web服务,只不过两者的侧重点不同。http
server侧重用作web服务器,而tomcat则侧重于作为轻量级的应用服务器。同时,两者也可以结合
起来使用,即可以将动态请求通过http
server转发至后端的tomcat来完成,http
server只处理静态请求。本文描述了如何配置apache与tomcat连接。

Redis存储Tomcat集群的Session,redistomcat

                Redis存储Tomcat集群的Session

如何

  做到把新开发的代码推送到到生产系统中部署,生产系统要能够零宕机、对使用用户零影响。

设想

  是使用集群来搞定,通过通知负载均衡Nginx,取下集群中的Tomcat节点,然后对Tomcat上的应用进行升级,再通知负载均衡Nginx,把Tomcat节点重新加载上去。依次这么做,把集群中的所有Tomcat都替换一次即可。

那么问题来了

  在取下Tomcat节点和加载新Tomcat节点时如何做到对用户无影响呢?方法很简单,共享Session。

下面

  我们用实例来说明此方案。我们的例子使用了一台Nginx做负载均衡,后端挂接了两台Tomcat,且每台Tomcat的Session会话
都保存到Redis数据库中。其中,Nginx配置为non-sticky运行模式,也即每一个请求都可以被分配到集群中的任何节点。当要上线新代码时,
只需简单地取下Tomcat实例,此时所有的访问用户会被路由到活动的Tomcat实例中去,而且由于会话数据都是保存在Redis数据库中,所以活跃用
户并不会受影响。当Tomcat更新完毕,又可以把此节点加入到Nginx中。

安装Nginx

  # sudo rpm -ivh nginx-1.4.2-1.el6.ngx.x86_64.rpm

修改配置文件/etc/nginx/nginx.conf,并添加下面的内容:

http {
upstream tomcat  {
        server localhost:8080;
        server localhost:8081;
    }
include      /etc/nginx/mime.types;
default_type  application/octet-stream;

修改配置文件/etc/nginx/conf.d/default.conf并替换location部分的内容:

location / {
    proxy_pass  http://tomcat;
  }

 

重启Nginx

# sudo service nginx restart

 

接下来

  安装两个Tomcat实例。由于我们是在同一台服务器上做的演示,要让两台Tomcat不发生冲突,需要修改第二个Tomcat实例的端口
号。由于Nginx配置为non-sticky运行模式,对每个请求采用的是Round-robin负载均衡方式,这意味着它会为每个请求都抽奖一个新会
话。

接着,下载并安装Redis。步骤省略,很简单。

最后

  我们需要配置Tomcat,让Tomcat把会话Session保存到Redis数据库。

我们要使用tomcat-redis-session-manager这样的第三方库,主页见:

 

注意

  此库并非开箱即用的,使用时需要做一些调整。你需要下载源码,并在更新了依赖库的版本后,重建项目。比如我使用了commons-
pool2-2.2.jar和jedis-2.6.1.jar依赖库。要记住把这些jar文件复制到每一个Tomcat实例的lib子目录下。

从
  https://github.com/xetorthio/jedis/downloads下载jedis作为java的redis客户端,
从
  https://github.com/jcoleman/tomcat-redis-session-manager/downloads下载tomcat的redis session manager插件,
从
  http://commons.apache.org/proper/commons-pool/download_pool.cgi下载apache的common pool包,
将
  这几个jar包拷贝到tomcat7的lib目录下。并在修改每一个Tomcat实例的context.xml配置文件:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
        host="localhost"
        port="6379"
        database="0"
        maxInactiveInterval="60" />

 

重启Tomcat实例

  可以检查到Redis确实保存了Tomcat的会话。然后我们对Tomcat实例取下或恢复时,访问用户确实没受影响。

 

R
edis存储 T omcat集群的 S ession 如何
做到把新开发的代码推送到到生产系统中部署,生产系统要能够零宕…

省市区,省市区数据库

都说我们要做模块化设计,而不要做功能化设计

什么是模块化设计,就是可插拔性高,组件化,想要就用,不要用拉倒,直接删除就行

什么是功能化设计,就是一个简单的功能,实现想要的效果,但是不够通用化,别人要用的话需要读懂你的代码,还需要复制黏贴很多代码这样效率不高

 

今天写了一个省市区三级联动的模块,写完后使用会非常方便,也很灵活

主要使用到的技术:jquery,redis,springMVC,MyBatis(springMVC和MyBatis无所谓,你用struts或者hibernate或者spring
data都行)

首先页面引入js

1 <script src="/js/jquery-2.2.4.min.js"></script>
2 <script src="/cityselect/js/jquery.cityselect.js"></script>

HTML中写入3个div块,这是互斥的,div#id不同就可以做到模块化可插拔

 1 <div id="city"> 
 2         <select class="prov"></select>  
 3         <select class="city" disabled="disabled"></select> 
 4         <select class="dist" disabled="disabled"></select> 
 5     </div> 
 6     
 7     <div id="city2"> 
 8         <select class="prov"></select>  
 9         <select class="city" disabled="disabled"></select> 
10         <select class="dist" disabled="disabled"></select> 
11     </div> 
12     
13     <div id="city3"> 
14         <select class="prov"></select>  
15         <select class="city" disabled="disabled"></select> 
16         <select class="dist" disabled="disabled"></select> 
17     </div> 

初始化JS:

    <script type="text/javascript">
        /**
         * 
         * @Description: 省市区三级联动api
         * Copyright: Copyright (c) 2016
         * 
         * ==============================
         * 参数说明
         * url:省市数据josn文件路径
         * prov:默认省份
         * city:默认城市
         * dist:默认地区(县)
         * nodata:无数据状态
         * required:必选项
         * ==============================
         * 
         * @author leechenxiang
         * @date 2016年6月16日 下午3:46:58
         * @version V1.0
         */
        $(function(){
            $("#city").citySelect({
                prov:"江苏省",
                city:"无锡市",
                dist:"南长区",
                required:false
            }); 

            $("#city2").citySelect({
                nodata:"none",
                required:false
            }); 

            $("#city3").citySelect({
                nodata:"none",
                required:false
            }); 

        });
    </script>

后台controller:

 1 /**
 2      * 
 3      * @Description: 获取所有的省市区列表
 4      * @return
 5      * @throws Exception
 6      * 
 7      * @author leechenxiang
 8      * @date 2016年6月16日 上午11:22:10
 9      */
10     @RequestMapping("/getCities")
11     @ResponseBody
12     public CitiesDataResult getCities() throws Exception {
13         CitiesDataResult areas = commonService.getAllCities();
14         return areas;
15     }

service:

 1 @Override
 2     public CitiesDataResult getAllCities() {
 3         // 取出缓存
 4         try {
 5             String citiesDataResult = jedisClient.get(REDIS_CITIES_KEY);
 6             if (!StringUtils.isBlank(citiesDataResult)) {
 7                 CitiesDataResult redisResult = JsonUtils.jsonToPojo(citiesDataResult, CitiesDataResult.class);
 8                 return redisResult;
 9             }
10         } catch (Exception e1) {
11             e1.printStackTrace();
12         }
13         
14         List<AreaProvince> provinceList = areaProvinceMapper.getProvinceList();
15         List<Province> pList = new ArrayList<Province>();
16         for (AreaProvince province : provinceList) {
17             int provinceId = province.getProvinceId();
18             String provinceName = province.getProvinceName();
19             
20             List<AreaCity> cityList = areaProvinceMapper.getCityListBypId(provinceId);
21             List<City> cList = new ArrayList<City>();
22             for (AreaCity city : cityList) {
23                 int cityId = city.getCityId();
24                 String cityName = city.getCityName();
25                 
26                 List<District> districtList = areaProvinceMapper.getDistrictListBycId(cityId);
27                 
28                 City c = new City();
29                 c.setN(cityName);
30                 c.setA(districtList);
31                 cList.add(c);
32             }
33             
34             Province p = new Province(provinceName, cList);
35             pList.add(p);
36         }
37         
38         CitiesDataResult result = new CitiesDataResult();
39         result.setCitylist(pList);
40         
41         // 放入缓存
42         try {
43             jedisClient.set(REDIS_CITIES_KEY, JsonUtils.objectToJson(result));
44         } catch (Exception e) {
45             e.printStackTrace();
46         }
47         
48         return result;
49     }

如果需要默认选中那么只需要对这3个参数赋值即可:

prov:"江苏省",
city:"无锡市",
dist:"南长区",

图片 1

对于省市区的数据源,可以存放在数据库表中,也可以直接存入js,作为一个json来调用即可

如果没有省市区可以淘一下万能的X宝,可以参考如下链接,真的是太强大了,把省市区直接细化到了极致:

省市区 数据库 脚本 excel

 

都说我们要做模块化设计,而不要做功能化设计
什么是模块化设计,就是可插拔性高,组件化,想要就用,不要用…

一、Tomcat连接器架构及协议

1、Tomcat连接器架构

基于Apache做为Tomcat前端的架构来讲,Apache通过mod_jk、mod_jk2或mod_proxy模块与后端的Tomcat进行数据交换。而对Tomcat来说,每个Web容器实例都有一个Java语言开发的连接器模块组件,即org.apache.catalina.Connector这个类。这个类的构造器可以构造两种类别的连接器:HTTP/1.1负责响应基于HTTP/HTTPS协议的请求,AJP/1.3负责响应基于AJP的请求。但可以简单地通过在server.xml配置文件中实现连接器的创建,但创建时所使用的类根据系统是支持APR(Apache
Portable Runtime)而有所不同。

APR是附加在提供了通用和标准API的操作系统之上一个通讯层的本地库的集合,它能够为使用了APR的应用程序在与Apache通信时提供较好伸缩能力时带去平衡效用。同时,需要说明的是,mod_jk2模块目前已经不再被支持了,mod_jk模块目前还apache被支持,但其项目活跃度已经大大降低。因此,目前更常用的方式是使用mod_proxy模块。
如果支持APR:
1、HTTP/1.1:org.apache.cotote.http11.Http11AprProtocol
2、AJP/1.3:org.apache.coyote.ajp.AjpAprProtocol
如果不支持APR:
HTTP/1.1: org.apache.coyote.http11.Http11Protocol
AJP/1.3: org.apache.jk.server.JkCoyoteHandler

2、连接器协议

Tomcat的Web服务器连接器支持两种协议:AJP和HTTP,它们均定义了以二进制格式在Web服务器和Tomcat之间进行数据传输,并提供相应的控制命令。
AJP(Apache JServ Protocol)协议:
目前正在使用的AJP协议的版本是通过JK和JK2连接器提供支持的AJP13,它基于二进制的格式在Web服务器和Tomcat之间传输数据,而此前的版本AJP10和AJP11则使用文本格式传输数据。

HTTP协议:诚如其名称所表示,其是使用HTTP或HTTPS协议在Web服务器和Tomcat之间建立通信,此时,Tomcat就是一个完全功能的HTTP服务器,它需要监听在某端口上以接收来自于商前服务器的请求。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签:
网站地图xml地图