一、初体验
创建一个名为springcloud-eureka-client
的项目
一. 导入相应的Maven依赖
</dependency><!--导入连接eureka服务器的客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!--导入springcloud依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
二. 修改application.properties
为application.yml
spring:
application:
#在服务器中的服务名称
name: provider-client
eureka:
client:
service-url:
#连接服务器的url
defaultZone: http://root:root@192.168.255.130:9988/eureka #该IP为eureka在Docker搭建的服务器IP
instance:
#每隔多长时间注册一次
lease-renewal-interval-in-seconds: 5
#每隔多长时间销毁一次
lease-expiration-duration-in-seconds: 5
#显示当前服务的ip地址和端口号
instance-id: ${spring.cloud.client.ip-address}:${server.port}
server:
port: 8081
注意: 需要指明spring.application.name
,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name
三. 在启动类添加注解驱动
//只能连接eureka注册中心
@EnableEurekaClient //表明自己是一个 Eureka Client
//可以连接其他的注册中心
@EnableDiscoveryClient
四. 在启动类同包下建立包controller
Java名为ProviderAdminController
@RestController //使用@RestController这个注解,不能返回jsp,html页面
public class ProviderAdminController {
@Value("${server.port}")
private String port;
@GetMapping(value = "hi")
public String sayHi() {
return "Hello Eureka, i am from port: " + port;
}
}
五. 通过浏览器访问
启动工程,打开 http://服务器搭建的EurekaIP:9988,即 Eureka Server 的网址:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5TCd6WfU-1594945461515)(https://pics.images.ac.cn/image/5f053242c8dcd.html)]
你会发现一个服务已经注册在服务中了,服务名为PROVIDER-ADMIN
, 端口为 8081,这时打开http://localhost:8081/hi
你会在浏览器上看到 :
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q95HYo84-1594945461517)(https://pics.images.ac.cn/image/5f05328e4c95f.html)]
二、Feign连接数据库
一、创建公共类
1.添加@Data Maven依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
2.编写实体类并且实现序列化
@Data
public class User implements Serializable {
private static final long serialVersionUID = -5059219722364235703L;
private Integer user_id;
private String user_username;
private String user_password;
private Integer user_first_login;
}
3.编写Service接口
public interface UserService {
public List<User> queryAllUser();
public User getUserById(int id);
public User getUser(String username,String password);
public boolean addUser(User user);
}
4.通过Maven的install将公共类安装到本地
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ak6ZNNWF-1594945461519)(https://pics.images.ac.cn/image/5f053a810eb1a.html)]
二、编写提供者
- 导入相关的依赖
<!--公共类依赖-->
<dependency>
<groupId>org.example</groupId>
<artifactId>wms-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--连接MySQL的相关依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--Mybatis相关依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!--Spring-cloud依赖-->
<!--注意是放在dependencies下面-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 在启动类同级包下创建
dao``````serviceimpl
包
dao
层包实现UserMapper
接口
public interface UserMapper {
public List<User> queryAllUser();
public User getUserById(@Param("id") int id);
public User getUser(@Param("username") String username, @Param("password") String password);
public int addUser(User user);
}
serviceimpl
实现Userservice
接口
@RestController
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
@RequestMapping("/queryAllUser")
public List<User> queryAllUser() {
return userMapper.queryAllUser();
}
@Override
@RequestMapping("/getUserById")
public User getUserById(int id1) {
System.out.println(id1);
return userMapper.getUserById(id1);
}
@Override
@RequestMapping("/getUser")
public User getUser(String username, String password) {
return userMapper.getUser(username, password);
}
@Override
@RequestMapping("/addUser")
public boolean addUser(@RequestBody User user) {
System.out.println(user.getUser_username());
int i=userMapper.addUser(user);
if(i>0){
return true;
}
return false;
}
@RequestMapping("/getUser1")
public User getUser1(@RequestBody Map<String,String> map){
System.out.println(map.get("username"));
System.out.println(map.get("password"));
return userMapper.getUser(map.get("username"),map.get("password"));
}
}
resources
资源文件夹编写Mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="swy.plus.wmsuserprovider.dao.UserMapper">
<select id="queryAllUser" resultType="cn.swy.pojo.User">
select * from `wms_user`
</select>
<select id="getUserById" resultType="cn.swy.pojo.User">
select * from `wms_user` where `user_id`=#{id}
</select>
<select id="getUser" resultType="cn.swy.pojo.User">
select * from `wms_user` where `user_username`=#{username} and `user_password`=#{password}
</select>
<insert id="addUser" parameterType="cn.swy.pojo.User">
insert into `wms_user`(`user_id`,`user_username`,`user_password`,`user_first_login`)
values (#{user_id},#{user_username},#{user_password},#{user_first_login})
</insert>
</mapper>
- 修改
application.properties
为application.yml
eureka:
client:
service-url:
defaultZone: http://root:root@192.168.255.130:9988/eureka #该IP为eureka在Docker搭建的服务器IP
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 5
server:
port: 8180
spring:
application:
name: wms-user-provider
datasource:
driver-class-name: com.mysql.jdbc.Driver #数据库驱动
url: jdbc:mysql://39.106.183.254:3306/wms_db
username: root
password: root #用户名密码
mybatis: #Mybatis驱动
mapper-locations: classpath:/mapper/**.xml #Mapper映射文件
type-aliases-packa:cn.swy.pojo #自己Common包下的实体类
- 修改启动类
添加注解
@EnableDiscoveryClient
@EnableFeignClients
三、编写消费者
- 添加Pom依赖
<!--添加公共类依赖-->
<dependency>
<groupId>org.example</groupId>
<artifactId>wms-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--导入etflix-eureka-client依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--导入consumer调用provider的feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!--Spring-cloud依赖-->
<!--注意是放在dependencies下面-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 在启动类同级包下创建
controller``````service
包
编写service
@FeignClient(name = "wms-user-provider")
public interface UserService {
@RequestMapping("/queryAllUser")
public List<User> queryAllUser();
@RequestMapping("/getUserById")
public User getUserById(@RequestParam("id") int id);
@RequestMapping("/getUser")
public User getUser(@RequestParam String username,@RequestParam String password);
@RequestMapping("/addUser")
public boolean addUser(@RequestBody User user);
@RequestMapping("/getUser1")
public User getUser(Map<String,String> map);
}
编写Controller控制器
@RestController
public class UserController {
@Resource
private UserService userService; //注意是本包下的service
@RequestMapping("/queryUser")
public List<User> queryAllUser(){
return userService.queryAllUser();
}
@RequestMapping("/getUser")
public User getUser(int id){
System.out.println("controller:"+id);
return userService.getUserById(id);
}
@RequestMapping("/getUser1")
public User getUser(String username,String password){
return userService.getUser(username, password);
}
@RequestMapping("/addUser")
public String addUser(User user){
boolean flag=userService.addUser(user);
if(flag){
return "添加成功";
}else{
return "添加失败";
}
}
@RequestMapping("/getUser2")
public User getUser1(String username,String password){
Map<String,String> map=new HashMap<String, String>();
map.put("username",username);
map.put("password",password);
return userService.getUser(map);
}
}
3.修改application.properties
为application.yml
- 修改启动类注解
@EnableDiscoveryClient
@EnableFeignClients
5.启动Provider和Consumer
6.浏览器访问IP:9988
7.测试浏览器输入localhost:8181/测试的方法名
三、Netflix Hystrix
一、什么是Hystrix
Hystrix
可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制。Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务出现故障时在整个系统所有的依赖服务调用中进行蔓延;同时Hystrix
还提供故障时的fallback
降级机制。
二、开启熔断器
Feign
是自带熔断器的,但默认是关闭的。需要在配置文件中配置打开它,在配置文件增加以下代码
feign:
hystrix:
enabled: true
三、创建熔断类
@Component
public class BusinessAdminFallback implements BusinessAdminFeign { //实现本包的Service
@Override
public String sayHi() {
return "请求失败了,请重试...";
}
}
四、声明熔断类
在@FeignClient
注解中增加fallback
属性声明熔断类
@FeignClient(value = "provider-admin", fallback = BusinessAdminFallback.class)
public interface BusinessAdminFeign {
@GetMapping(value = "hi")
String sayHi();
}
五、测试熔断器
此时我们关闭服务提供者,再次请求http://localhost:12000/hi
浏览器会显示
请求失败了,请重试...