lucene、solr全文搜索
lucene是一款搜索引擎技术,并非产品,而solr是搜索引擎所在服务器。
应用场景:
1:网站头部的搜索
2:APP端头部搜索
3:做成搜索产品
搜索原理:
简介:
Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。
lucene的工作方式
lucene提供的服务实际包含两部分:一入一出。所谓入是写入,即将你提供的源(本质是字符串)写入索引或者将其从索引中删除;所谓出是读出,即向用户提供全文搜索服务,让用户可以通过关键词定位源。
写入流程
源字符串首先经过analyzer处理,包括:分词,分成一个个单词;去除stopword(可选),将源中需要的信息加入Document的各个Field中,并把需要索引的Field索引起来,把需要存储的Field存储起来,将索引写入存储器,存储器可以是内存或磁盘
读出流程
用户提供搜索关键词,经过analyzer处理,对处理后的关键词搜索索引找出对应的Document,用户根据需要从找到的Document中提取需要的Field
概念
analyzer:
Analyzer是分析器,它的作用是把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语,这里说的无效词语是指英文中的“of”、“the”,中文中的“的”、“地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率
document:
用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中的。用户进行搜索,也是以Document列表的形式返回
field:
一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。 Field有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否对该Field进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重要,下面举例说明:还是以刚才的文章为例子,我们需要对标题和正文进行全文搜索,所以我们要把索引属性设置为真,同时我们希望能直接从搜索结果中提取文章标题,所以我们把标题域的存储属性设置为真,但是由于正文域太大了,我们为了缩小索引文件大小,将正文域的存储属性设置为假,当需要时再直接读取文件;我们只是希望能从搜索解果中提取最后修改时间,不需要对它进行搜索,所以我们把最后修改时间域的存储属性设置为真,索引属性设置为假。上面的三个域涵盖了两个属性的三种组合,还有一种全为假的没有用到,事实上Field不允许你那么设置,因为既不存储又不索引的域是没有意义的
lucene入门示例
1:新建一个工程
2:导入所需jar包
入库
1:新建一个入库的实体对象
2:入库IndexWrite
代码如下:
/**
* 文档
* @author likang
* @date 2017-12-22 上午9:50:21
*/
public class Ariclte implements Serializable{
private static final long serialVersionUID = 1L;
private Long aid;
private String title;
private String context;
public Long getAid() {
return aid;
}
public void setAid(Long aid) {
this.aid = aid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
}
/**
* 入库:将一篇文件存储到搜索库中
* 出库:根据关键词,从搜索库中搜索对应的匹配信息
* @author likang
* @date 2017-12-22 上午9:49:26
*/
public class HelloLucene {
/**
* 入库
* @throws Exception
*/
@Test
public void createIndex() throws Exception{
//初始化数据文章
Ariclte ariclte = new Ariclte();
ariclte.setAid(Long.valueOf(1));
ariclte.setTitle("Lucene是一款很好的搜索引擎");
ariclte.setContext("Lucene是一款搜索引擎技术,产品有百度,谷歌等");
Directory directory = FSDirectory.open(new File("./indexLucene"));//创建搜索库路径目录
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);//搜索库的分词器
/**
* MaxFieldLength.LIMITED:文章长度有限制
* UNLIMITED:无限制
*/
//lucene中入库的核心接口API
IndexWriter indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);
/**
* Index:
* NOT_ANALYZED:代表支持索引,不支持分词,不支持创建对象,不支持存储
* ANALYZED:代表支持索引,支持分词,支持创建对象,支持存储
* ANALYZED_NO_NORMS:代表支持索引,支持分词,不支持创建对象,不支持存储
* NOT_ANALYZED_NO_NORMS:代表支持索引,不支持分词,不支持创建对象
* NO:都不支持
*
* Store:
* YES:存储
* NO:不存储
*
*/
Field field1 = new Field("aid", ariclte.getAid().toString(), Store.YES, Index.NOT_ANALYZED);
Field field2 = new Field("title", ariclte.getTitle(), Store.YES, Index.NO);
Field field3 = new Field("context", ariclte.getContext(), Store.YES, Index.ANALYZED);
Document document = new Document();
document.add(field1);
document.add(field2);
document.add(field3);
//将document,写入到搜索库中
indexWriter.addDocument(document);
//关闭搜索库
indexWriter.close();
}
}
出库
/**
* 出库
* 根据关键词---匹配3个
* @throws Exception
*/
@Test
public void searchIndex() throws Exception{
//获取搜索库的位置
Directory directory = FSDirectory.open(new File("./indexLucene"));
//搜索库的分词器
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
//lucene搜索出库API
IndexSearcher indexSearcher = new IndexSearcher(directory);
/**
* 第一个参数代表之前的库版本信息
* 第二参数代表要搜索的字段
* 第三个参数代表使用的分词器
*/
QueryParser queryParser = new QueryParser(Version.LUCENE_30, "context", analyzer);
//输入的关键词
Query query = queryParser.parse("Lucene");
/**
* 第一个参数代表搜索的关键词
* 第二个参数代表根据关键词匹配显示的个数
*/
TopDocs topDocs = indexSearcher.search(query, 3);
//所有搜索对象--集合/数组中
ScoreDoc[] sds = topDocs.scoreDocs;
List<Ariclte> list = new ArrayList<Ariclte>();
for (ScoreDoc sd : sds) {
int index = sd.doc;//文章对应的下标
Document document = new Document();
document = indexSearcher.doc(index);
Ariclte ariclte = new Ariclte();
ariclte.setAid(Long.valueOf(document.get("aid").toString()));
ariclte.setTitle(document.get("title"));
ariclte.setContext(document.get("context"));
list.add(ariclte);
}
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
System.out.println("标题:"+list.get(i).getTitle());
System.out.println("简短标题:"+list.get(i).getContext());
System.out.println("点击进入:www.baidu.com");
}
}
}
shiro权限管理
Shiro 是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。
特点:
1:易于理解的 Java Security API
2:简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等)
3:对角色的简单的签权(访问控制),支持细粒度的签权
4:支持一级缓存,以提升应用程序的性能
5:内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境
6:异构客户端会话访问
7:非常简单的加密 API
8:不跟任何的框架或者容器捆绑,可以独立运行
Shiro 主要有四个组件:
SecurityManager:
典型的 Facade,Shiro 通过它对外提供安全管理的各种服务
Authenticator:
1:对“Who are you ?”进行核实。通常涉及用户名和密码
2:这个组件负责收集 principals 和 credentials,并将它们提交给应用系统,如果提交的credentials 跟应用系统中提供的 credentials 吻合,就能够继续访问。否则需要重新提交 principals 和 credentials,或者直接终止访问。
Authorizer:
1:身份份验证通过后,由这个组件对登录人员进行访问控制的筛查,比如“who can do what”, 或者“who can do which actions”。
2:Shiro 采用“基于 Realm”的方法,即用户(又称 Subject)、用户组、角色和 permission 的聚合体。
Session Manager:
这个组件保证了异构客户端的访问,配置简单。它是基于 POJO/J2SE 的,不跟任何的客户端或者协议绑定
Shiro 的认证和签权可以通过 JDBC、LDAP 或者 Active Directory 来访问数据库、目录服务器或者 Active Directory 中的人员以及认证 / 签权信息。SessionManager 通过会话 DAO 可以将会话保存在 cache 中,或者固化到数据库或文件系统中
shiro可以做什么?
1:支持认证跨一个或多个数据源(LDAP,JDBC,kerberos身份等)
2:执行授权,基于角色的细粒度的权限控制
3:增强的缓存的支持
4:支持web或者非web环境,可以在任何单点登录(SSO)—ticket或集群分布式会话中使用
5:主要功能是:认证,授权,会话管理和加密
Shiro支持三种方式实现授权过程:
1:编码实现
2:注解实现
3:jsp tablib标签
Shiro提供了一套JSP标签库来实现页面级的授权控制
在使用Shiro标签库前,首先需要在JSP引入shiro标签
注解:
Shiro注解支持AspectJ、Spring、Google-Guice等
@RequiresAuthentication:
可以用于用户类/属性/方法
@RequiresGuest
表明该用户需为”guest”用
@RequiresPermissions(“account:create”)
当前用户需拥有制定权限户 于表明当前用户需是经过认证的用户
@RequiresRoles
当前用户需拥有制定角色
@RequiresUser
当前用户需为已认证用户或已记住用户
Shiro的具体功能点如下:
- 身份认证/登录,验证用户是不是拥有相应的身份
- 授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限
- 会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的
- 加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储
- Web支持,可以非常容易的集成到Web环境,Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率
- shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去
- 提供测试支持
- 允许一个用户假装为另一个用户(如果他们允许)的身份进行访问
- 记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了
shiro入门示例
步骤:
1:在启动容器中,增加shiro的filter过滤器
2:增加shiro的配置文件信息,shiro.xml
3:在shiro.xml配置文件中,增加自己的自定义relam(认证(查询用户名和密码信息)、授权(角色信息),自己写一个查询数据库的用户名、密码、角色等用户信息)
4:在控制层controller,增加登录(login())和退出方法(logout())
5:提示对应的登录返回信息即可
代码:
web.xml中增加配置:
<!-- shiro过滤器 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>*.jhtml</url-pattern>
<url-pattern>*.json</url-pattern>
</filter-mapping>
shiro配置文件:shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!-- Shiro's main business-tier object for web-enabled applications -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myShiroRealm" /> <!--自定义过滤(拦截) -->
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- 項目自定义的Realm -->
<bean id="myShiroRealm" class="com.xdl.shiro.realm.MyShiroRealm">
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login.jhtml" />
<property name="successUrl" value="/loginsuccess.jhtml" />
<property name="unauthorizedUrl" value="/error.jhtml" />
<property name="filterChainDefinitions">
<!--是有先后顺序的 -->
<value>
/index.jhtml = authc
/login.jhtml = anon
/checkLogin.json = anon
/loginsuccess.jhtml = anon
/logout.json = anon
/** = authc
</value>
</property>
</bean>
<!-- 用户授权信息Cache -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<!-- AOP式方法级权限检查 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
</beans>
shiro.xml配置文件说明:
”shiroFilter” 这个bean里面的各个属性property的含义:
(1)securityManager:这个属性是必须的,没什么好说的,就这样配置就好。
(2)loginUrl:没有登录的用户请求需要登录的页面时自动跳转到登录页面,可配置也可不配置。
(3)successUrl:登录成功默认跳转页面,不配置则跳转至”/”,一般可以不配置,直接通过代码进行处理。
(4)unauthorizedUrl:没有权限默认跳转的页面。
(5)filterChainDefinitions,对于过滤器就有必要详细说明一下:
1)Shiro验证URL时,URL匹配成功便不再继续匹配查找(所以要注意配置文件中的URL顺序,尤其在使用通配符时),故filterChainDefinitions的配置顺序为自上而下,以最上面的为准
2)当运行一个Web应用程序时,Shiro将会创建一些有用的默认Filter实例,并自动地在[main]项中将它们置为可用自动地可用的默认的Filter实例是被DefaultFilter枚举类定义的,枚举的名称字段就是可供配置的名称
3)通常可将这些过滤器分为两组:
anon,authc,authcBasic,user是第一组认证过滤器
perms,port,rest,roles,ssl是第二组授权过滤器
注意user和authc不同:当应用开启了rememberMe时,用户下次访问时可以是一个user,但绝不会是authc,因为authc是需要重新认证的 user表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe
说白了,以前的一个用户登录时开启了rememberMe,然后他关闭浏览器,下次再访问时他就是一个user,而不会authc
4)举几个例子
/admin=authc,roles[admin] 表示用户必需已通过认证,并拥有admin角色才可以正常发起’/admin’请求
/edit=authc,perms[admin:edit] 表示用户必需已通过认证,并拥有admin:edit权限才可以正常发起’/edit’请求
/home=user 表示用户不一定需要已经通过认证,只需要曾经被Shiro记住过登录状态就可以正常发起’/home’请求
5)各默认过滤器常用如下(注意URL Pattern里用到的是两颗星,这样才能实现任意层次的全匹配)
/admins/**=anon 无参,表示可匿名使用,可以理解为匿名用户或游客
/admins/user/**=authc 无参,表示需认证才能使用
/admins/user/**=authcBasic 无参,表示httpBasic认证
/admins/user/**=user 无参,表示必须存在用户,当登入操作时不做检查
/admins/user/**=ssl 无参,表示安全的URL请求,协议为https
/admins/user/=perms[user:add:] 参数可写多个,多参时必须加上引号,且参数之间用逗号分割,如/admins/user/=perms[“user:add:,user:modify:*”] 当有多个参数时必须每个参数都通过才算通过,相当于isPermitedAll()方法
/admins/user/**=port[8081]当请求的URL端口不是8081时,跳转到schemal://serverName:8081?queryString 其中schmal是协议http或https等,serverName是你访问的Host,8081是Port端口,queryString是你访问的URL里的?后面的参数
/admins/user/=rest[user]根据请求的方法,相当于/admins/user/=perms[user:method],其中method为post,get,delete等
/admins/user/=roles[admin]参数可写多个,多个时必须加上引号,且参数之间用逗号分割,如/admins/user/=roles[“admin,guest”]当有多个参数时必须每个参数都通过才算通过,相当于hasAllRoles()方法
dubbo+zk/Redis 分布式RPC框架
Dubbo是什么?
Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000多个服务提供30多亿次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
核心部分
远程通讯:
提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式
集群容错:
提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持
自动发现:
基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
RPC能做什么?
透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者
dubbo+ZK架构图
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor:统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
调用关系说明:
0. 服务容器负责启动,加载,运行服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
开发步骤:
1:增加dubbo的配置文件(提供者)
zk的通讯注册地址
dubbo的对外暴露接口的地址
对外暴露并注册的接口(zk)
2:增加获取服务接口的配置文件dubbo(消费者)
配置dubbo调用的接口暴露地址
获取要调用消费的接口bean组件
使用步骤:
1:开启zk的服务,将dubbo的接口注册到服务中
2:启动dubbo的监控中心,监控提供者和消费者的接口调用和注册信息
代码:
配置文件内容:
提供者:
<!-- 具体的实现bean -->
<bean id="testService" class="com.xdl.service.impl.TestServiceImpl" />
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="provider" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="29014" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.xdl.service.TestService" ref="testService" />
消费者:
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer" />
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="testService" interface="com.xdl.service.TestService" />
环境搭建步骤:
1:新建一个提供者的maven工程
2:导入所需jar包
3:配置dubbo的配置文件信息
4:添加一个接口和接口实现类,并配置到文件中
5:写一个测试main方法,将接口注册到zk中
1:新建一个消费者的maven工程
2:导入所需jar包
3:配置dubbo的配置文件信息
4:添加一个main方法,直接测试调用接口信息
运行步骤:
1:启动zk服务
2:启动tomcat服务
3:进入dubbo的监控平台
4:运行提供者main方法
5:运行消费者的main方法
代码参考:《provider》《consumer》工程文件
资料参考地址:
Nginx代理
传说中的代理模式,在互联网早期就已经出现了,属于硬件的设施F5 开源代理模式,比如nginx,而nginx代理,分为正向代理,反向代理和透明代理。 而在使用的时候,使用比较多得还是正向代理和反向代理,nginx默认的配置是正向代理 其中在企业中,用的比较多得是反向代理
正向代理:
正向代理(forward proxy):是一个位于客户端(用户A)和原始服务器(origin server)(目标服务器)之间的服务器(代理服务器),为了从原始服务器取得内容,客户端向代理服务器发送一个请求并指定目标(原始服务器),然后代理服务器向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的配置才能使用正向代理。一般情况下,如果没有特别说明,代理技术默认是指正向代理技术。
举例: 比如客户A,想访问原始资源C,但是客户A不能直接访问到目标资源服务器C,客户A需要配置一些所有信息(代理服务器B),桥接到目标服务器C,就可以间接的获取C端的资源
对于目标服务器C来说,不知道是客户在访问,而只是识别到代理服务器B
作用:
1:访问原来不能访问的内容
我们抛除复杂的网络路由情节来看图,图中路由器从左到右为R1,R2假设最初用户A要访问目标服务器需要经过R1和R2路由器这样一个路由节点,如果路由器R1或者路由器R2发生故障,那么就无法访问目标服务器了。但是如果用户A让代理服务器去代替自己访问目标服务器,由于代理服务器没有在路由器R1或R2节点中,而是通过其它的路由节点访问目标服务器,那么用户A就可以得到目标服务器的数据了。现实中的例子就是“翻墙”。不过自从VPN技术被广泛应用外,“翻墙”不但使用了传统的正向代理技术,有的还使用了VPN技术。
2:缓存cache(不常用)
主要是提高代理服务器的宽带流量,目前不流行了。
Cache(缓存)技术和代理服务技术是紧密联系的(不光是正向代理,反向代理也使用了Cache(缓存)技术。还如上图所示,如果在用户A访问目标服务器某数据之前,已经有人通过代理服务器访问过目标服务器上得数据,那么代理服务器会把数据保存一段时间,如果有人正好取该数据,那么代理服务器不再访问目标服务器,而把缓存的数据直接发给用户A。这一技术在Cache中术语就叫Cache命中。如果有更多的像用户A的用户来访问代理服务器,那么这些用户都可以直接从代理服务器中取得数据,而不用千里迢迢的去目标服务器下载数据了。
3:对客户端访问授权,上网进行认证(设置安全组规则)
防火墙作为网关,用来过滤外网对其的访问。假设用户A和用户B都设置了代理服务器,用户A允许访问互联网,而用户B不允许访问互联网(这个在代理服务器上做限制)这样用户A因为授权,可以通过代理服务器访问到目标服务器,而用户B因为没有被代理服务器授权,所以访问目标服务器时,数据包会被直接丢弃。
4:代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
目标服务器并不知道访问自己的实际是用户A,因为代理服务器代替用户A去直接与目标服务器进行交互。如果代理服务器被用户A完全控制(或不完全控制),会惯以“肉鸡”术语称呼
反向代理:
反向代理(reverse proxy):和正向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样
用户A始终认为它访问的是目标服务器而不是代理服务器,但实用际上反向代理服务器接受用户A的应答,从目标服务器中取得用户A的需求资源,然后发送给用户A。由于防火墙的作用,只允许代理服务器访问目标服务器。尽管在这个虚拟的环境下,防火墙和反向代理的共同作用保护了目标服务器,但用户A并不知情。
作用::
1:负载均衡
2:集群模式,目前只支持反向代理
当反向代理服务器不止一个的时候,我们甚至可以把它们做成集群,当更多的用户访问目标服务器的时候,让不同的代理服务器去应答不同的用户,然后发送不同用户需要的资源。
透明代理:
透明代理:透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改编你的request fields(报文),并会传送真实IP。注意,加密的透明代理则是属于匿名代理,意思是不用设置使用代理了。 透明代理实践的例子就是时下很多公司使用的行为管理软件
资料参考地址:
Activiti工作流
参考资料PPT/PDF:
《Activiti工作流应用与实例 - 教学1》
《Activiti工作流应用与实例 - 教学2》
《Activiti工作流应用与实例 - 教学3》
《Activiti工作流应用与实例 - 教学4》