微服务
微服务的特点:
● 单一职责: 微服务中每一个服务都对应唯一 的业务能力,做到单一职责
● 微: 微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但”五脏俱全”。
● 面向服务: 面向服务是说每个服务都要对外暴露Rest风格服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
● 自治: 自治是说服务间互相独立,互不干扰
。团队独立: 每个服务都是一个独立的开发团队,人数不能过多
。技术独立: 因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
。前后端分离: 采用前后端分离开发,提供统一Rest接口,后端不用再为PC.移动段开发不同接口
。数据库分离: 每个服务都使用自己的数据源
。部署独立: 服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
简单的微服务业务:
分别建立两个项目user-service 和consurm-demo, user-service通过服务端发送数据,consurm-demo调用user-service发送的数据。
user-service查询数据的代码(端口为8081):
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User queryById(@PathVariable("id") int id){
return userService.queryById(id);
}
}
consurm-demo调用user-service主要代码:
@RestController
@Reques tMapp ing ("Consumer")
public class ConsumerController [
@Autowired
private RestTemplate template;
@GetMapping("{id}" )
public User queryById (@PathVariable("id") Long id){
String url = "http://localhost:8081/user/" + id;
User user = template.getForobject(url, User.class) ;
return user;
}
}
这种代码有很多显而易见的缺点和弊端,所以选择 Eureka加以改进
Eureka案例
构建项目
创建一个集合工程,父工程中导入依赖:
<groupId>com.it.demo</groupId>
<artifactId>clod-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>user-service</module>
<module>consurm-demo</module>
<module>eureka-serve</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<mapper.starter.version>2.0.3</mapper.starter.version>
<mysql.version>5.1.32</mysql.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--通用Mapper启动器-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper.starter.version}</version>
</dependency>
<!-- mysqL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建eureka-service工程,并引入服务端依赖
<!--引入eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
启动类加@EnableEurekaServer注解
@EnableEurekaServer
@SpringBootApplication
public class EurekaServe {
public static void main(String[] args) {
SpringApplication.run(EurekaServe.class);
}
}
user-service和consurm-demo都导入eureka的客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka- client </artifactId>
</dependency>
在user-service和consurm-demo启动类添加 @EnableDiscoveryClient注解(支持多种服务注册中心,包括eureka)
eureka-service的applicayion.yml
server:
port: 8082
spring:
application:
name: eureka-serve
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8082/eureka #注册自己
启动,浏览器查看结果
user-service的applicayion.yml添加
server:
port: 8081
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://localhost:8082//eureka
启动,查看结果
使用eureka后consurm-demo获取service信息@RequestMapping(“consumer”)
public class ConsumerController {
@Autowired
private RestTemplate template;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
public User queryById(@PathVariable("id") int id){
//从服务id获取实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
//从实例中获取Ip和端口
ServiceInstance instance = instances.get(0);
/* instance.getHost()*//*ip地址*//* + ":" + instance.getPort()*//*端口*/
String url = "http://"+ instance.getHost() + ":" + instance.getPort()+"/user/" + id;
User user = template.getForObject(url,User.class);
return user;
}
}
Eureka高可用(集群方式)
创建多个相互注册的EurekaService,它们之间会数据共享,访问任何一个EurekaService都可以获得他们的注册信息:
示例:
复制一个EurekaService
修改端口,实现相互注册
启动服务:
在user-serve和consurm-demo中配置这两个EurekaService
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8082/eureka,http://127.0.0.1:8088/eureka