初步学习理解微服务以及写一个小demo
本文有部分内容参照:漫画:什么是微服务? 该作者以漫画的形式表达,更易理解。
微服务是什么?
微服务是指开发一个单个小型的但有业务功能的服务,每个服务都有自己的处理和轻量通讯机制,可以部署在单个或多个服务器上。微服务也指一种种松耦合的、有一定的有界上下文的面向服务架构。也就是说,如果每个服务都要同时修改,那么它们就不是微服务,因为它们紧耦合在一起;如果你需要掌握一个服务太多的上下文场景使用条件,那么它就是一个有上下文边界的服务,这个定义来自DDD领域驱动设计。简而言之,微服务就是将我们传统的MVC架构,所有的业务子模块都集成在一个很重的JVM进程当中。这种单体架构的好处就是便于管理,所有的代码在同一项目中,但是当产品规模越来越大,其坏处也很明显。
缺点一:项目过于臃肿当大大小小的功能模块都集中在同一项目的时候,整个项目必然会变得臃肿,让开发者难以维护。
缺点二:资源无法隔离就像刚刚小灰的经历一样,整个单体系统的各个功能模块都依赖于同样的数据库、内存等资源,一旦某个功能模块对资源使用不当,整个系统都会被拖垮。
缺点三:无法灵活扩展当系统的访问量越来越大的时候,单体系统固然可以进行水平扩展,部署在多台机器上组成集群。但是这种扩展并非灵活的扩展。比如我们现在的性能瓶颈是支付模块,希望只针对支付模块做水平扩展,这一点在单体系统是做不到的。
微服务的优点:
1.独立部署,灵活扩展传统的单体架构是以整个系统为单位进行部署,而微服务则是以每一个独立组件(例如用户服务,商品服务)为单位进行部署。
2.资源的有效隔离微服务设计的原则之一,就是每一个微服务拥有独立的数据源,假如微服务A想要读写微服务B的数据库,只能调用微服务B对外暴露的接口来完成。这样有效避免了服务之间争用数据库和缓存资源所带来的问题。
3.团队组织架构的调整微服务设计的思想也改变了原有的企业研发团队组织架构。传统的研发组织架构是水平架构,前端有前端的团队,后端有后端的团队,DBA有DBA的团队,测试有测试的团队。
下图是小型的微服务架构图:
spring-cloud的注册中心是用的REST协议(远程调用,传json):基于http的一种规范。所有的服务与调用者(网官)都会去注册中心注册
第一步:写一个注册服务
spring-regist:工程名
导包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Jackson Json处理工具包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
写主类
Regist.java
package com.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer //注册服务器 public class Register { public static void main(String[] args) { SpringApplication.run(Register.class, args); } }
application.properties
#服务器端口号 server.port=1110 #服务名称 spring.application.name=eureka-server eureka.client.register-with-eureka=false eureka.client.fetch-registry=false #该服务的地址 eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
然后再浏览器中将地址输入回车
第二步:写服务工程
导包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.s 4000 pringframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Jackson Json处理工具包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
主类(在创建工程的时候会自动创建该类)
package com.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @EnableEurekaClient //注册客户端 @ComponentScan("com.action") //扫描com.action包 public class Server { public static void main(String[] args) { SpringApplication.run(Server.class, args); } }
控制层
package com.action; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class Add { @Value("${server.port}") private String port; @RequestMapping("/add") public String add(@RequestParam(defaultValue="1") int x,@RequestParam(defaultValue="1") int y) { // int n=x+y; // return n+""; // if(true) // throw new RuntimeException(); return x+y+"-"+port; } }
属性文件
SEspring.application.name=service-add server.port=2222 eureka.client.serviceUrl.defaultZone=http://localhost:1110/eureka/
可以注册多个客户端,只需要修改端口号。
再次打开注册中心的界面,此时会出现客户端的端口号
将客服端的地址输入地址栏,如图:
第三步:写网官类(springcloud-getway)
导包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Jackson Json处理工具包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
主类:
package com.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @EnableEurekaClient //注册为客户端 @EnableDiscoveryClient //去注册中心发现客户端 @ComponentScan("com.action") @EnableHystrix //熔断 public class Getway { public static void main(String[] args) { SpringApplication.run(Getway.class, args); } }
RestTemplateConfig类:
package com.action; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @Primary @LoadBalanced //负载均衡 public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
测试类:
package com.action; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @RestController public class Test { @Autowired private RestTemplate restTemplate; @RequestMapping("/add") @HystrixCommand(fallbackMethod="error")//如果有客户端挂掉 就告诉他调用这个方法 public String add(int x, int y) { //http://127.0.0.1:2220/add?x=1&y=2 String url = "http://你的注册中心里你要访问的客户端的名字(注册中心客户端上的注册名称)/add?x="+x+"&y="+y; String response =restTemplate.getForObject(url, String.class); return response; } public String error(int x, int y) { return "500"; } }
然后在浏览器输入网官的地址,就可以调用在注册中心有注册的客户端的地址。
完毕。
不知道写的内容是否有点多,一方面是给自己看的。另一方面是给想学习微服务的码农了解的。
- Pytorch入门学习(六)--- 加载数据以及预处理(初步)--- 只为了更好理解流程
- 一步一个脚印学习WCF之一WCF概要(中)之客户端与服务-WCF服务的创建与调用Demo
- 一个Demo学习Android的服务
- 面向对象OO 设计、架构终极理解, 以及如何学习一个领域
- thrift学习第二步,一个简单的双向通信demo以及原理讲解,以及注意事项
- 用类名做方法的返回值类型 在学习Java的初始阶段,很多同学使用基本数据类型定义变量和引用类型定义变量以及使用类名做方法的返回值类型常常不知所以。今天我以自己的解读方式和个人的理解作一个简单的解释,和
- tensorflow学习二:概念知识和一个帮助理解的demo
- 一个后端的前端学习之旅——4.第一个demo上线以及关于前端框架我的看法
- [学习笔记]Java代码构建一个线程池的自己学习写的实例,用这个你会更好的理解文章内容
- Uinty3D 一个动画播放以及射线查询的Demo
- SNDCP学习笔记三(服务功能理解)
- 对 Message 和 Handle 的机制理解 必须写一个例子学习
- FFMPEG理解一个偶然遇到了ffmpeg,看起来不多,而且通用性很强,算是一个扎实的技术。 研究了两天了,万事开头难啊。 主要是新手学习一个东西的时候,没有宏观的概念,如果猛地往某个细节去钻,往往碰
- IOS学习:在一个UIViewController中实现侧边菜单的思路及demo
- 学习笔记:使用Web Service Software Factory开发简易留言本服务以及Mobile调用实现-1.创建Service
- [学习笔记]UML小结以及基于领域模型的系统设计初步
- 一步一个脚印学习WCF之一WCF概要(中)之客户端与服务
- 一步一个脚印学习WCF系列之WCF契约设计—1-服务契约ServiceContractAttribute
- 一个Demo学完Android中所有的服务
- [cocos2d-x]学习demo一些未理解的知识点