在进行分布式处理的时候如何进行程序功能划分;
业务中心:在进行一些庞大的项目设计过程之中,应该有更加完善的业务处理,这样所有的客户端(服务器),用这些业务中心的操作就可以完成具体的功能。
数据库集群:解决了数据的存储问题,以及数据的分片管理。
对于分布式的项目开发按照历史的发展经历过如下的一些技术:
CORBA:公共对象请求代理架构,它是一种开发的标准,而且也是许多语言都支持的开发标准。
RMI(远程方法调用):该技术是sun提出的,该技术出现的最大特征是希望可以与CORBA进行市场的竞争,于是这技术出现时,很多公司不认可这些技术。
用户->接口(存根)->接口及实现类(骨架)
发现RMI很好用,单不如CORBA广泛。后基于CORBA设计了RMI-IIOP协议,这个协议应用在了EJB上。
用户->WEB容器->EJB容器(WebSphere、WebLogic、JBoss)
优秀的理论,糟糕的实现。后因XML的出现,基于XML作为交互语言的WebService登场了。
1、.Net 与JAVA通过SOAP协议相互调用(WebService=XML+SOAP).
2、WebService技术开发,存在如下问题:
速度太慢了;
想要采用远程接口方式调用,就要利用开发工具生成一堆工具类代码;
3、基于上述SOA思想出现,即将所有的服务统一管理起来,就成了服务总线,那么所有的开发者直接调用里面的服务就完成一些功能。后来又不断出现了许多的RPC开发技术,其中国内具有代表性的dubbo开发技术,不过成长最快的Rest,因为JSON的广泛引用,就如同最初XML技术造就了WebService,JSON造就了Rest服务;
利用Rest进行RPC技术实现,这样的操作速度很快,而且占用的带宽要少,SpringCloud就将整个Rest作为了RPC实现技术,并且这一技术已经开始出现现有行业的统一之势。而且Spring Cloud依照Spring Boot开发技术,可以实现项目的打包发布以及单独运行,这一点符合当前云时代的开发要求。
SpringCloud整体核心架构只有一点:Rest服务,也就是说在整个SpringCloud配置过程之中,所有的配置处理都是围绕着Rest完成的,在整个Rest处理之中,一定要有两个端:服务的提供者(Provider)及服务的消费者(Consumer),所以对于整个SpringCloud基础结构就是如下所示:
用户-反向代理-Web微服务-(Restful即服务地址:端口)-微服务提供者
微架构缺点:只有业务层才能规划为微架构,
REST指的一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。满足这些约束条件和原则的应用程序或设计就是 RESTful。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
客户端(WEB)-注册中心-业务层-数据层-MySQL
Web端通过Nginx实现负载均衡,业务端通过在Eureka注册中心之中进行注册,通过robbon进行业务端负载均衡配置。通过feign伪造接口实现,将robbon伪造为接口。Hystrix熔断处理机制,保证某一个微服务即使出现了问题,依然可以正常使用。(原理为某个微服务出现问题,返回定义好的错误信息,而不是报错或无返回)
Feign-robbon-Eureka-Hystrix熔断处理机制
客户端-调用微服务X(RPC前端/springBoot)-Rest(zuul代理)-调用微服务X(RPC后端SpringCloud)-数据层-数据库。
通过Zuul代理的用户只需要知道指定路由的路径,就可以访问指定微服务信息,这样更好的体现了java中的“key=value”的设计思想,而且所有的微服务Zuul进行代理。
springCloud设计的时候提供有一个SpringCloudConfig程序组件,利用这个组件就可以直接基于GIT或SVN来进行配置文件的管理。
springBoot-zuul代理及Eureka注册服务-可通过GitHup管理的Config及微服务。
在整体设计上SpringCloud更好的实现了RPC架构,而且使用了Rest作为通讯的基础,且大量使用的netfix公司的产品技术,这些技术也有了可靠的保证。
对于rest基础架构实现处理是Springcloud核心所在。
创建一个microcloud的整体父pom项目,将创建三个子模块: microcloud-api子模块,作为公共的信息导入配置模块; microcloud-provider-dept-8001作为服务提供者,该提供者负责使用Mybatis与数据库的交互;
Microcloud-consumer-80:作为微服务调用的客户端使用。
Ps:springCloud离不开springBoot,所以需要配置此依赖包。
Deptno(long)、dname(String)、dbname(保存的数据库的名字)
创建一个Rest提供者的项目模块,在这个模块主要定义要使用的数据库脚本;
由于在整个微服务里面需要进行负载均衡操作,所以我们本次在使用的时候加入了数据库的名称信息。
所谓微服务的核心本质就是JSON的传输,那么既然现在要求使用Mybatis进行数据库操作,所以应该在项目里面配置Druid的数据库连接池,而后对外进行项目的发布。
①microcloud-provider-dept-8001:修改pom.xml配置文件,追加相关的依赖程序支持包。
②microcloud-provider-dept-8001:创建IDeptDAO数据操作接口,这个接口里面将提供有三个数据操作方法。
③microcloud-provider-dept-8001:修改Application.yml配置文件,追加mybatis和服务的相关配置信息;
④microcloud-provider-dept-8001:定义src/main/resources/mybatis/mybatis.cfg.xml配置文件:
⑤microcloud-provider-dept-8001:修改src/main/resources/mybatis/mapper/cn/mldn/Dept.xml配置文件;
⑥microcloud-provider-dept-8001:建立IDeptService接口,做业务实现:
⑦microcloud-provider-dept-8001:定义接口的运行主类。
⑧microcloud-provider-dept-8001:进行业务接口测试编写。
⑨microcloud-provider-dept-8001:建立DeptRest服务类。
@Controller
Public class DeptRest{
@ResquestMapping(value=“dept/get”,method=RequestMethod.GET)
Public Dept get(){
Return xx;
}
}
(C:windowsSystem32driversetchosts)
追加“127.0.0.1 dept-8001.com”
调用get操作;dept-8001.com:8001/dept/get/1;
调用list操作;调用add操作。
Server:
port:80
@Configuration
Public class RestConfig{
@Bean
Public RestTemplate getRestTemplate(){
Return new RestTemplate();
}
}
127.0.0.1 client.com
7、进行代码测试调用
调用数据返回任务:http://client.com/consumer/dept/get?id=1?
所有Rest服务最终都是暴露在公网,Rest访问,安全性是首要因素。
如果要想进行安全的验证处理,那么首先一定要先在服务提供方进行处理。
如果你现在配置了安全框架,则在启动时会出现如下提示信息:
Using default security password:73df5......
security:
Basic:
Enabled:true #启用springSecurity的安全配置项。
User:
name:mldnjava #认证用户名
password:hello #认证密码
role: #授权角色
随后在项目之中访问Rest服务接口http://client.com/consumer/dept/get?id=1?,此时在访问的时候会要求用户输入用户名与密码,这个时候有一个更简化方法进行内容的输入:http://mldnjava:hello@client.com/consumer/dept/get?id=1?
在安全的开发之中,对于Rest服务提供者不可能被用户直接访问的,所以肯定需要一个rest客户端springboot进行调用,可是现在Rest提供者的服务上有了认证信息,那么该如何访问呢?
如果这个时候在Rest客户端上直接使用用户名和密码做加密处理,那么根本无法访问,此时会出现有401的错误代码,因为认证出现了错误。是因为所有的认证的处理操作,应该以头信息的模式进行处理。而后使用base64进行加密处理后才可以得到一个正确的访问路径。
HttpHeaders headers = new HttpHeaders();
String auth=“user:password”
byte[] encodeAuth =Base64.getEncoder().encode(auth.getbytes(Charset.forName(“US-ASCII”)))
String authHeader = “basic ”+ new String(encodeAuth);
headers.set(“Authorization”,”authHeader”);
在进行授权的头信息内容配置的时候加密的信息一定要与“Basic ”之间有一个空格。
对于rest而言,在spring课程讲过,里面如果进行参数的传递,有各自方式,例如:各种页面的路径信息组成,如果要是传递复杂内容,建议你在整个处理的时候就去使用那些页面的参数传递模式。
整个Rest项目中的一个问题所在,所有的Rest都是基于Http协议的应用,这种应用上所有的web容器一般都会提供有一个Session机制,也就是说每一个用户访问之后,如果该用户一直连接,则认为该用户一直被服务器保存状态,但微服务有可能并发访问几W或几十W人,那么如果所有的Session状态都被维护着?
request.getSession().getId();
随后进行提供者的Rest连接访问,http://mldnjava:hello@dept-9=8001.com:8001/dept/sessionId:
application.yml配置文件
Security:
Session:always(保存状态,服务器内存可能被占满)
Stateless(无状态)
不管你以后的项目或者支持类中是否有设置的无状态的问题,你最好都进行一下设置,否则你的Rest服务将受到严重的内存困扰,最严重的就是内存溢出。
在进行Rest服务开发的时候,为了保证安全所有的程序里面都需要进行Spring-Security安全认证处理,可是之前所进行的认证处理都是在application.yml配置文件完成的,这样配置明显不符合逻辑,如果你需要开发的微服务很多,这些微服务都要求使用统一的用户名和密码的时候就非常不方便了。所以现在最简单的做法是进行统一的设置。
WebSecurityConfig extends WebSecurityConfigurerAdapter{
Public void config(HttpSecurity http)
{
//表示所有访问都必须进行认证处理后才能正常进行
http.httpBasic().add().authorizeRequest().anyRequest().fullyAuthenticated();
//所有的Rest服务一定要设置为无状态,以提升操作性能。
http.sessionManager().sessionCreationPolicy(SessionCreation.Policy.STATELESS);
}
}
<dependency>
<groupId>cn.mldn<groupId>
<artifactId>microcloud-security<artifactId>
<dependency>
5、【microcloud-provider-member-8001】删除掉application.yml中与安全有关的配置项。
security:
Basic:
Enabled:true #启用springSecurity的安全配置项。
User:
name:mldnjava #认证用户名
password:hello #认证密码
role: #授权角色
由于现在所写的安全处理类是在程序启动类的子包之中,应该可以自动扫描到。
6访问地址:http://mldnjava@hello@dept-8001.com:8001/dept/sessionId