<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>cn.cduestcgroupId>
<artifactId>springcloudartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<junit.version>4.12junit.version>
<lombok.version>1.18.10lombok.version>
<log4j.version>1.2.12log4j.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Greenwich.SR1version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.1.4.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.12version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.1.1version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
dependencyManagement>
project>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloudartifactId>
<groupId>cn.cduestcgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>cn.cduestc.springcloudgroupId>
<artifactId>springcloud-apiartifactId>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
project>
package cn.cduestc.springcloud.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@NoArgsConstructor
@Accessors(chain = true) //开启该类的链式写法
//实体类必须实现Serializable接口,保证在微服务架构项目模块之间进行通信时可以序列化
public class Dept implements Serializable{
private Long id;
private String name;
//微服务架构一个服务对应一个数据库,不同信息可能存在不同数据库,该字段表示存在哪个数据库
private String db_source;
}
<dependency>
<groupId>cn.cduestc.springcloudgroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-testartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
configuration>
<mapper namespace="cn.cduestc.springcloud.mapper.DeptMapper">
<insert id="addDept" parameterType="Dept">
INSERT INTO db01.dept(name,db_source) VALUES (#{name},DATABASE())
insert>
<select id="selectById" parameterType="Long" resultType="Dept">
SELECT * FROM db01.dept WHERE id=#{id}
select>
<select id="selectAll" resultType="Dept">
SELECT * FROM db01.dept
select>
mapper>
server:
port: 8081
#mybatis相关配置
mybatis:
#配置实体类的包
type-aliases-package: cn.cduestc.springcloud.pojo
#配置mybatis配置文件的路径
config-location: classpath:mybatis/mybatis-config.xml
#配置mybatis的mapper文件的位置
mapper-locations: classpath:mybatis/mapper/*.xml
#spring相关配置
spring:
#给该模块取个名字
application:
name: springcloud-provider-dept
datasource:
#更换连接数据库的数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
package cn.cduestc.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableEurekaClient //配置后该类为eureka客户端启动类
@EnableDiscoveryClient //配置后可以发现服务的信息
public class DeptProvider {
public static void main(String[] args) {
SpringApplication.run(DeptProvider.class,args);
}
}
package cn.cduestc.springcloud.controller;
import cn.cduestc.springcloud.pojo.Dept;
import cn.cduestc.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/dept/add")
public boolean addDept(Dept dept){
return deptService.addDept(dept);
}
@GetMapping("/dept/select/{id}")
public Dept selectOne(@PathVariable("id") Long id){
return deptService.selectById(id);
}
@GetMapping("/dept/selectAll")
public List<Dept> selectAll(){
return deptService.selectAll();
}
}
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-ribbonartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>cn.cduestc.springcloudgroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
package cn.cduestc.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration //加上该注解,将该类标记为配置类,可以在该类中配置springboot的相关配置
public class ConfigBean {
@Bean //将该方法返回的bean注册到容器中
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
package cn.cduestc.springcloud.controller;
import cn.cduestc.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class DeptController {
/**
* 分析:消费者不能有service层,所以使用restTemplate进行远程调用,需要将restTemplate的bean注册到容器中
*/
@Autowired
private RestTemplate restTemplate;
//当进行远程调用时,url的前缀是固定的,所有我们可以设置一个常量
private static final String REST_URL_PREFIX = "http://localhost:8081";
@RequestMapping("/consumer/dept/add")
public boolean addDept(Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
}
@RequestMapping("/consumer/dept/select/{id}")
public Dept selectOne(@PathVariable("id") Long id){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/select/"+id,Dept.class);
}
@RequestMapping("/consumer/dept/selectAll")
public List<Dept> selectAll(){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/selectAll",List.class);
}
}
springcloud是服务消费者在controller中使用RestTemplate进行基于http的远程调用。
dubbo是使用注册中心,在不同模块的yml配置文件中配置相同注册中心地址,服务提供者将服务放入注册中心,在添加@Reference注解后,服务消费者会在服务中心去获取该服务接口,从而达到不同模块之间的调用
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
<version>1.4.6.RELEASEversion>
dependency>
server:
port: 7001
#Eureka配置
eureka:
instance:
hostname: localhost #Eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #fetch-registry为false时,表示自己为注册中心
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #注册中心的地址
@EnableEurekaServer //配置该注解,表示该启动类是eureka的服务端启动类,可以接收其他服务注册进来
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #配置注册中心地址
instance:
instance-id: springcloud-provider-dept8001 #配置服务名称
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
info:
app.name: springcloud-zhanghu
company.name: cduestc
//该接口用于发现服务,其实现类中存储了服务的一些信息
@Autowired
private DiscoveryClient discoveryClient;
//输出eureka的服务发现信息(用来获取注册进来的服务的一些信息)
@GetMapping("/dept/discovery")
public Object discovery(){
//获取哪些服务已经注册
List<String> services = discoveryClient.getServices();
System.out.println("discovery=>service=>"+services);
//根据某个服务名获取该服务的实例
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for (ServiceInstance instance : instances) {
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()+"\t"
);
}
return this.discoveryClient;
}
@EnableDiscoveryClient //服务的发现
eureka:
client:
service-url:
# 单体:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #注册中心的地址
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ # 集群
/**这里不应该使用"http://localhost:8081",因为这里写死了,直接去访问8081端口下的服务,而我们使用
* Eureka做了注册中心,且做了注册中心集群,使用了Ribbon做负载均衡,所以不应该将服务地址写死,这里的
* 服务地址应该是一个变量
*/
//private static final String REST_URL_PREFIX = "http://localhost:8081";
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-ribbonartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
server:
port: 80
#Eureka相关配置
eureka:
client:
register-with-eureka: false #配置为false之后,不会向服务中心注册该服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
@LoadBalanced //因为做远程调用的是RestTemplate,所以负载均衡也应该在RestTemplate上面做,所以在注册Bean时添加@LoadBalanced
@EnableEurekaClient //配置为Eureka客户端启动类
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
<version>1.4.6.RELEASEversion>
dependency>
package cn.cduestc.springcloud.controller;
import cn.cduestc.springcloud.pojo.Dept;
import cn.cduestc.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
//获取单个数据
@GetMapping("/dept/select/{id}")
@HystrixCommand(fallbackMethod = "hystrixSelectOne") //添加该注解后,表示对该服务添加了hystrix熔断机制,在该服务挂掉时,会调用备用服务
public Dept selectOne(@PathVariable("id") Long id){
Dept dept = deptService.selectById(id);
//判断如果输入错误id,没有查询到数据,那么抛出一个运行时异常
if (dept == null){
throw new RuntimeException("您输入的id没有对应的值哦!!!");
}
return dept;
}
//该方法是在服务挂掉后,启用hystrix熔断机制调用的备用方法
public Dept hystrixSelectOne(@PathVariable("id") Long id){
return new Dept()
.setId(id)
.setName("对不起,"+id+"没有对应的数据")
.setDb_source("没有对应的信息,当然没有数据库哦");
}
}
@EnableCircuitBreaker //开启hystrix熔断器
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrix-dashboardartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-ribbonartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>cn.cduestc.springcloudgroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
@EnableHystrixDashboard //开启Hystrix的Dashboard监控
//注册一个servlet,对hystrix进行流监控 固定代码
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
servletRegistrationBean.addUrlMappings("/actuator/hystrix.stream");
return servletRegistrationBean;
}
@EnableCircuitBreaker //开启hystrix熔断器
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zuulartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrix-dashboardartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-hystrixartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-ribbonartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>cn.cduestc.springcloudgroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
server:
port: 9527
#给zuul取个名字
spring:
application:
name: springcloud-zuul
#Eureka配置
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #配置注册中心地址
instance:
instance-id: zuul9527.com #zuul状态显示名称
prefer-ip-address: true #显示ip
#zuul配置
zuul:
routes:
mydept: {serviceId: springcloud-provider-dept,path: /mydept/**} #配置map集合,用于确定路由的统一访问路径
# mydept.serviceId: springcloud-provider-dept
# mydept.path: /mydept/**
ignored-services: "*" #表示要忽略的访问路径,因为我们配置了新的访问路径,需要将原来的路径禁止;配通配符隐藏全部
prefix: /hu #给所有的访问添加统一的访问前缀
#点进服务展示相关信息
info:
app.name: springcloud-zhanghu
company.name: cduestc
@EnableZuulProxy //开启路由代理
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
package cn.cduestc.springcloud.config;
import org.springframework.cloud.openfeign.FeignClient;
import cn.cduestc.springcloud.pojo.Dept;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@FeignClient(value = "springcloud-provider-dept")
public interface FeignConfit {
@GetMapping("/dept/selectAll")
List<Dept> selectAll3();
}
@Autowired
private FeignConfit FeignConfit;
@GetMapping("/consumer/dept/selectAll4")
public List<Dept> selectAll2(){
return FeignConfit.selectAll3();
}