微服务的理解
最近这一个月,按照leader浩哥的要求,在项目中应用了微服务和restful架构,受益颇多,不但是接触了一个新思想而且立马进行实践,这种感觉还是很好的。现在趁着提测中间的空档总结一下。
项目的整体采用了微服务的架构,什么是微服务呢,自己的理解就是将一个大服务(项目)划分为多个子(服务)项目。拿现在的项目来说就是把整个项目分为登录、资产管理、域名、下发和回源等子项目,每个子项目提供一种服务,一个开发人员负责开发一个子项目,部署也是子项目单独部署,项目和项目之间通过Http请求获取数据,应用最广的就是登陆子模块,所有的请求都是经过登陆后再利用get、post等进行转发,登陆信息也在这时候添加到请求头中。那么采用微服务有什么好处呢,个人感觉就是轻量,可以根据需求大小单独大量部署需求旺盛的服务,而其他的服务不需要部署,和之前大量部署整个项目相比的话,部署微服务显然会更轻量。整个的项目架构图如下
可以看到下发这个服务需求比较大,那么就可以在服务器上部署两个这个服务,如果需求再次增加,那么就继续增加这个服务,而其他服务则不需要增加,多个部署的上层是Nginx,其他服务调用直接通过域名进行调用,实际上是Nginx做了转发;除此之外,另一个好处是在git上开发的时候不会造成冲突,因为每个人在大项目中负责的是一个子项目,一个单独的git地址,所以永远也不会造成冲突。
在开发时利用的开发工具是idea,idea开发是有project和Module的概念,利用这个概念可以将子项目分为不同的Module,如图所示,资产分为api、service、job和mq四个module,api这个module向前端和其他子服务提供数据调用,这个api对应的包名就是controller;service这个module是服务处理来自api的请求,包括逻辑处理、数据访问等,包括service包、repository包、mapper包和对应的xml文件包等;job这个module提供定时任务的服务;mq这个module提供的是消息队列的服务;这样在代码中各个部分就是完美的解耦;总结一下就是api提供对外接口,service内部处理;job定时任务;mq消息队列,这样就告别了单单依靠各个包名来区别服务,各个module之间通过在pom建立以来关系,比如api依赖service,service依赖job,pom中代码如下:
<dependency>
<groupId>com.yourcompany.projectname</groupId>
<artifactId>service</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
需要说明的是:需要下载的模板等静态文件都是直接放在前端的module中,而不是放在需要下载的service的module中。在开发时候使用springboot进行开发,这是目前感觉Java服务器开发最方便的方式,能够满足微服务快速开发的需求,springboot框架提供了对restful的支持。由于springboot内嵌服务器,因此在部署的时候也会变得更简单,不需要再安装Tomcat等,启动服务的时候直接使用不挂断的命令启动就好,方便的很,下边是启动的一种命令
nohup java -jar 打包后的jar.jar &
RESTful的理解
RESTful是一种规范,是微服务的一种标准,rest更容易在代码中看出来,这是开发时候的规范,通过一段代码+注解的方式说明:
/**
* @Author:txxs
* @Date: 2017/4/28
* @Time:11:46
*/
@RestController
//版本号用v1表示
@RequestMapping("/v1")
public class CarController {
/**
*添加资源,POST方法,/server单数
**/
@RequestMapping(path="/car",method = {RequestMethod.POST})
public ResponseEntity addCar(@RequestBody Car car)throws Exception{
}
/**
*获取资源的列表,用复数的形式,GET方法
**/
@RequestMapping(path="/cars", method={RequestMethod.GET})
@ResponseBody//这是多余的,@RestController中包含
public ResponseEntity getCarList(Car car) throws Exception{
//方法名可以根据业务等取名,查询是的参数放入对象中,但是在开发的时候遇到的问题是获取列表的种类多种多样,
//获取的时候,需要在service中进行复杂判断
}
/**
*获取某一个资源,用单数的形式,GET方法
**/
@RequestMapping(path="/car", method={RequestMethod.GET})
public ResponseEntity getCar(Car car) throws Exception{
}
/**
*修改资源的属性,PUT方法,通过URL拼接的方式,
*URL中包含要修改字段的名称,修改的值通过消息体传递,
*这一点感觉不匹配因为改一个字段就要传递一个对象消耗有点大,
*所以低版本的Http可以使用patch方法,但是Http规范并不怎么支持
**/
@RequestMapping(path="/car/{id}/status",method = {RequestMethod.PUT})
public ResponseEntity carStatus( @PathVariable("id") String id, @RequestBody Car car){
}
/**
*修改资源,PUT方法,全量修改的话传递对象就比较适合
**/
@RequestMapping(path="/car",method = {RequestMethod.PUT})
public ResponseEntity editCar(@RequestBody Car car)throws Exception{
}
/**
*删除某一个资源,用单数的形式,DELETE方法,通过URL拼接的方式
**/
@RequestMapping(path="/car/{id}",method = {RequestMethod.DELETE})
public ResponseEntity deleteCar( @PathVariable("id") String id)throws Exception{
//开发的时候的问题是,可能会有批量删除,delete在Http规范中不支持传送消息体,如果批量删除那就得改用post方法
}
}
对RESTful总结起来就是:
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。