父工程:SpringCloud
配置文件 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>SpringCloud_provider</module>
<module>SpringCloud_consumer</module>
<module>SpringCloud_eureka</module>
<module>SpringCloud_provider_balance</module>
<module>SpringCloud_gateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<groupId>org.example</groupId>
<artifactId>SpringCloud</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<packaging>jar</packaging>
</properties>
<!--SpringCloud包依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
服务注册中心:Erueka **pom.xml**
<?xml version="1.0" encoding="UTF-8"?>
<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>SpringCloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloud_eureka</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<packaging>jar</packaging>
</properties>
<!--依赖包-->
<dependencies>
<!--eureka-server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 1111
spring:
application:
name: SpringCloudeureka #应用名称,会在Eureka中作为服务的id标识(serviceId)
eureka:
client:
register-with-eureka: false #是否将自己注册到Eureka中
fetch-registry: false #是否从eureka中获取服务信息
service-url:
defaultZone: http://localhost:1111/eureka #EurekaServer的地址
启动类
开启E
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
服务的提供者:SpringCloud_provider
那个 SpringCloud_provider_balance 也是一样的,唯一不同的是application.yml的server端口号 需要引入 Erueka 的客户端包
配置文件 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>SpringCloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloud_provider</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<packaging>jar</packaging>
</properties>
<!--依赖包-->
<dependencies>
<!--JPA包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--web起步包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka-server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--MySQL驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--测试包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 2222
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: 数据库用户名
password: 数据库密码
url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
application:
name: SpringCloudprovider #服务的名字,不同的应用,名字不同,如果是集群,名字需要相同
#指定eureka服务地址
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:1111/eureka
启动类
package com.example;
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;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class UserProviderApplication {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication.class,args);
}
}
@EnableEurekaClient 将 Erueka 客户端发现功能配置进启动类 @EnableDiscoveryClient 并开启 Eureka 客户端发现功能
接下来从 dao 到 controller
pojo
package com.example.pojo;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "tb_user")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String username;
@Column
private String password;
@Column
private String name;
@Column
private Integer age;
@Column
private Integer sex;
@Column
private Date birthday;
@Column
private Date created;
@Column
private Date updated;
@Column
private String note;
}
Dao
直接继承 JpaRepository,会自动生成 没用Mapper注解是因为没用Mybatis
package com.example.dao;
import com.example.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDao extends JpaRepository<User,Integer> {
}
Service 接口
package com.example.service;
import com.example.pojo.User;
public interface UserService {
User findByUser(Integer id);
}
实现类 @Autowired注入dao
package com.example.service.Impl;
import com.example.dao.UserDao;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User findByUser(Integer id) {
User user = userDao.findById(id).get();
return user;
}
}
Controller
这里用 @RestController 可以自动以 json 格式返回值 如果用 @Controller 则需要搭配 @ResponesBody
package com.example.controller;
import com.example.pojo.User;
import com.example.service.UserService;
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;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/find/{id}")
public User findById(@PathVariable("id")Integer id){
return userService.findByUser(id);
}
}
服务的消费者:SpringCloud_consumer
消费端需要配置服务通信:fegin 熔断器:hystrix Eureka的客户端包
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>SpringCloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>SpringCloud_consumer</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<packaging>jar</packaging>
</properties>
<!--依赖包-->
<dependencies>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka-server依赖-->
<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-hystrix</artifactId>
</dependency>
<!--配置feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
applicaion.yml
server:
port: 3333
spring:
application:
name: SpringCloucconsumer #服务名字,不能有下划线
#指定eureka服务地址
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:1111/eureka
# 配置熔断策略:
hystrix:
command:
default:
circuitBreaker:
# 强制打开熔断器 默认false关闭的。测试配置是否生效
forceOpen: false
# 触发熔断错误比例阈值,默认值50%
errorThresholdPercentage: 50
# 熔断后休眠时长,默认值5秒
sleepWindowInMilliseconds: 10000
# 熔断触发最小请求次数,默认值是20
requestVolumeThreshold: 10
execution:
isolation:
thread:
# 熔断超时设置,默认为1秒
timeoutInMilliseconds: 2000
启动类
要注册进Erueka:@EnableEurekaClient 要发现:@EnableDiscoveryClient 要熔断:@EnableCircuitBreaker 要通信:@EnableFeignClients 因为Fdign集成l了Ribbon,可以直接在RestTemple上写 @LoadBalanced开启负载均衡
package com.example;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
消费端要有和提供方相同的 pojo 和 一个Controller
pojo
package com.example.pojo;
import java.util.Date;
public class User {
private Integer id;
private String username;
private String password;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
private Integer age;
private Integer sex;
private Date birthday;
private Date created;
private Date updated;
private String note;
}
Controller(普通)
package com.example.controller;
import com.example.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
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
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "defaultFailBack")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/{id}")
@HystrixCommand
public User queryById(@PathVariable("id")Integer id){
List<ServiceInstance> springcloud_provider = discoveryClient.getInstances("SPRINGCLOUD_PROVIDER");
int port = 0;
for (ServiceInstance serviceInstance : springcloud_provider) {
port = serviceInstance.getPort();
}
String url = "http://springCloudprovider:"+port+"/user/find/" + id;
User user = restTemplate.getForObject(url, User.class);
return user;
}
public User failBack(Integer id){
User user = new User();
user.setUsername("服务降级,默认处理");
return user;
}
public User defaultFailBack(){
User user = new User();
user.setUsername("Default-服务降级,默认处理!");
return user;
}
}
Controller(Feign负载分担) 负载分担接口
package com.example.feign;
import com.example.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("springCloudprovider")
public interface UserClient {
@RequestMapping("/user/find/{id}")
User findById(@PathVariable("id")Integer id);
}
负载分担控制类
package com.example.controller;
import com.example.feign.UserClient;
import com.example.pojo.User;
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;
@RestController
@RequestMapping("/feign")
public class ConsumerFeignController {
@Autowired
private UserClient userClient;
@RequestMapping("/{id}")
public User queryById(@PathVariable("id")Integer id){
return userClient.findById(id);
}
}
|