本文共 18948 字,大约阅读时间需要 63 分钟。
简介
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。 配套参考资料: (有很详细的翻译文档 ) Springcloud版本pom文件生成可借助网站:最简单的微服务架构会有四个工程
父工程:microservice通用模块(M):microservice-common
服务提供者(C):microservice-student-provider-1001 服务消费者(C):microservice-student-consumer-80 微服务架构注意点: 1、springboot、springcloud版本在父工程定义; 2、由于通用模块无需操作数据库,springboot启动默认会读取数据库,所以得添加以下==注解 ==@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class});
3、分布式jpa需要在启动类上添加@EntityScan("com.javaxl.*.*");
4、消费者需要添加配置类获取org.springframework.web.client.RestTemplate,springcloud底层是通过RestTemplate来调用提供者的服务的。
传统项目拆分成微服务架构图 创建父工程microservice 父工程是一个maven项目,一般创建方式即可,父工程的主要用途是锁定pom依赖包版本。由于springcloud2X停止更新,这里我们采用稳定的低版本,配套的springboot版本为1x版本 Pom.xml配置如下:4.0.0 com.zxp microservice 1.0-SNAPSHOT war UTF-8 1.8 1.8 1.1.10 org.springframework.cloud spring-cloud-dependencies Edgware.SR4 pom import org.springframework.boot spring-boot-dependencies 1.5.13.RELEASE pom import com.alibaba druid-spring-boot-starter ${druid.version}
创建通用模块microservice-common
通用模块主要存放实体类、工具包等被整个微服务框架所使用的代码。创建一个简单的springboot模块即可。相关代码如下: **pom.xml ** 指定父工程,导入相关依赖4.0.0 com.zxp microservice 1.0-SNAPSHOT microservice-common 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java org.springframework.boot spring-boot-maven-plugin
**MicroserviceCommonApplication.java **
MicroserviceCommon主要存放实体类、工具包但是启动项默认加载数据库所以我们要排除数据源读取package com.zxp.microservicecommon;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})//排除数据源读取public class MicroserviceCommonApplication { public static void main(String[] args) { SpringApplication.run(MicroserviceCommonApplication.class, args); }}
**Student.java **
package com.zxp.microservicecommon.entity;import javax.persistence.*;import java.io.Serializable;@Entity@Table(name="t_springcloud_student")public class Student implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; @Column(length=50) private String name; @Column(length=50) private String grade; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGrade() { return grade; } public void setGrade(String grade) { this.grade = grade; } }
创建服务提供者microservice-student-provider-1001
创建一个简单的springboot模块,这里服务提供者需要操作数据库并且被浏览器所访问,固需要添加相关配置如下 pom.xml 指定父工程,导入相关依赖4.0.0 com.zxp microservice 1.0-SNAPSHOT microservice-student-provider-1001 1.8 com.javaxl microservice-common org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java org.springframework.boot spring-boot-starter-tomcat com.alibaba druid-spring-boot-starter org.springframework springloaded org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-maven-plugin
application.yml
server: port: 1001 context-path: /spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 username: root password: 123 jpa: hibernate: ddl-auto: update show-sql: true
MicroserviceStudentProvider1001Application.java
package com.zxp.microservicestudentprovider1001;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.domain.EntityScan;@EntityScan("com.zxp.*.*")@SpringBootApplicationpublic class MicroserviceStudentProvider1001Application { public static void main(String[] args) { SpringApplication.run(MicroserviceStudentProvider1001Application.class, args); }}
StudentRepository.java
package com.zxp.microservicestudentprovider1001.repository;import com.zxp.microservicecommon.entity.Student;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;public interface StudentRepository extends JpaRepository, JpaSpecificationExecutor { }
StudentService
package com.zxp.microservicestudentprovider1001.service;import com.zxp.microservicecommon.entity.Student;import java.util.List;public interface StudentService { public void save(Student student); public Student findById(Integer id); public Listlist(); public void delete(Integer id); }
StudentServiceImpl
package com.zxp.microservicestudentprovider1001.service.impl;import com.zxp.microservicecommon.entity.Student;import com.zxp.microservicestudentprovider1001.repository.StudentRepository;import com.zxp.microservicestudentprovider1001.service.StudentService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class StudentServiceImpl implements StudentService { @Autowired private StudentRepository studentRepository; @Override public void save(Student student) { studentRepository.save(student); } @Override public Student findById(Integer id) { return studentRepository.findOne(id); } @Override public Listlist() { return studentRepository.findAll(); } @Override public void delete(Integer id) { studentRepository.delete(id); }}
StudentProviderController
package com.zxp.microservicestudentprovider1001.controller;import com.zxp.microservicecommon.entity.Student;import com.zxp.microservicestudentprovider1001.service.StudentService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@RequestMapping("/student")public class StudentProviderController { @Autowired private StudentService studentService; @PostMapping(value="/save") public boolean save(Student student){ try{ studentService.save(student); return true; }catch(Exception e){ return false; } } @GetMapping(value="/list") public Listlist(){ return studentService.list(); } @GetMapping(value="/get/{id}") public Student get(@PathVariable("id") Integer id){ return studentService.findById(id); } @GetMapping(value="/delete/{id}") public boolean delete(@PathVariable("id") Integer id){ try{ studentService.delete(id); return true; }catch(Exception e){ return false; } }}
创建服务消费者microservice-student-consumer-80
服务消费者主要是通过restful api来调用提供者的接口,不需要操作数据库,相关配置如下pom.xml
4.0.0 com.zxp microservice 1.0-SNAPSHOT microservice-student-consumer-80 1.8 com.javaxl microservice-common org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java org.springframework.boot spring-boot-starter-tomcat org.springframework springloaded org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-maven-plugin
application.yml
server: port: 80 context-path: /
MicroserviceStudentConsumer80Application
由于消费者主要是通过restful api来调用提供者的接口,不需要操作数据库但是启动项默认加载数据库所以我们要排除数据源读取package com.zxp.microservicestudentconsumer80;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})public class MicroserviceStudentConsumer80Application { public static void main(String[] args) { SpringApplication.run(MicroserviceStudentConsumer80Application.class, args); }}
SpringCloudConfig
package com.zxp.microservicestudentconsumer80.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configurationpublic class SpringCloudConfig { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); }}
StudentConsumerController
package com.zxp.microservicestudentconsumer80.controller;import com.zxp.microservicecommon.entity.Student;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController@RequestMapping("/student")public class StudentConsumerController { private final static String SERVER_IP_PORT = "http://localhost:1001"; @Autowired private RestTemplate restTemplate; @PostMapping(value="/save") private boolean save(Student student){ return restTemplate.postForObject(SERVER_IP_PORT+"/student/save", student, Boolean.class); } @GetMapping(value="/list") public List成功结果图如下 http://localhost:1001/student/list http://localhost/student/list 以上传统项目拆分成微服务完成list(){ return restTemplate.getForObject(SERVER_IP_PORT+"/student/list", List.class); } @GetMapping(value="/get/{id}") public Student get(@PathVariable("id") Integer id){ return restTemplate.getForObject(SERVER_IP_PORT+"/student/get/"+id, Student.class); } @GetMapping(value="/delete/{id}") public boolean delete(@PathVariable("id") Integer id){ try{ restTemplate.getForObject(SERVER_IP_PORT+"/student/delete/"+id, Boolean.class); return true; }catch(Exception e){ return false; } }}
Eureka简介:Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka包含两个组件:Eureka Server和Eureka Client。 Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。 Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。 在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。 Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。类似zookeeper,Eureka也是一个服务注册和发现组件,是SpringCloud的一个优秀子项目,不过比较坑的是,Eureka2版本已经停止更新了。但是Eureka1版本还是很稳定,功能足够用,所以还是有必要学习下。
但是这里有
几个常用的服务注册与发现组件比对 服务注册与发现原理 Eureka的使用 前面说过eureka是c/s模式的 server服务端就是服务注册中心,其他的都是client客户端,服务端用来管理所有服务,客户端通过注册中心,来调用具体的服务; 我们先来搭建下服务端,也就是服务注册中心;1.新建 module microservice-eureka-server-2001
2.在pom文件中加入eureka-server依赖4.0.0 com.zxp microservice 1.0-SNAPSHOT microservice-eureka-server-2001 1.8 org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.boot spring-boot-starter-test test org.springframework springloaded org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-maven-plugin
3.在yml文件中添加Eureka服务端相关信息
server: port: 2001 context-path: /eureka: instance: hostname: localhost #eureka注册中心实例名称 client: register-with-eureka: false #false 由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己。 fetch-registry: false #false 由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka注册中心交互的地址,查询服务和注册服务用到
4.在启动类中添加@EnableEurekaServer注解
package com.zxp.microserviceeurekaserver2001;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer@SpringBootApplicationpublic class MicroserviceEurekaServer2001Application { public static void main(String[] args) { SpringApplication.run(MicroserviceEurekaServer2001Application.class, args); }}
测试连接
http://localhost:2001/ 搭建成功截图如下 向Eureka中注册服务提供者 这里我们在原来的服务提供者项目 microservice-student-provider-1001 上面直接修改: 首先pom.xml修改,加上eureka客户端依赖:org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-config
然后application.yml上加上配置:
eureka: instance: hostname: localhost #eureka客户端主机实例名称 appname: microservice-student #客户端服务名 instance-id: microservice-student:1001 #客户端实例名称 prefer-ip-address: true #显示IP client: service-url: defaultZone: http://localhost:2001/eureka #把服务注册到eureka注册中心
这里的defaultZone要和前面服务注册中心的暴露地址一致;
最后 启动类加上一个注解 @EnableEurekaClient;package com.zxp.microservicestudentprovider1001;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.autoconfigure.domain.EntityScan;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EntityScan("com.zxp.*.*")@EnableEurekaClient@SpringBootApplicationpublic class MicroserviceStudentProvider1001Application { public static void main(String[] args) { SpringApplication.run(MicroserviceStudentProvider1001Application.class, args); }}
然后我们测试下,先启动服务注册中心,再启动这个服务提供者;
然后运行:http://localhost:2001/ 服务提供者成功注册截图如下 报错解决 解决方案如下 1、首先在服务提供者(生产者)项目pom.xml里加入actuator监控依赖:org.springframework.boot spring-boot-starter-actuator
2、最后服务提供者(生产者)项目application.yml加上info配置:
info: groupId: com.zxp.microservice artifactId: microservice-student-provider-1001 version: 1.0-SNAPSHOT userName: http://zxp.com phone: 123456
结果图如下
转载地址:http://rurzi.baihongyu.com/