认识并学会springCloud的使用
SpringCloud将现在一些流行的技术整合到一起,实现如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。主要涉及的组件有
netflix
Eureka:注册中心
Zuul:服务网关
Ribbon:负载均衡
Feign:服务调用
Hystix:熔断器
环境准备:一个数据库和表tb_user
1.创建一个父工程,和子模块consumer-demo,eureka-server,eureka-server2(两个是eureka的高可用性练习),user-server,(user-server2是对user server的集群练习可以不要)zuul-Demo。
(完整代码:https://gitee.com/mountaincold/cloudDemo)
2. 创建注册中心 eureka-server
1.pom.xml 导入依赖 eureka服务端
2. 创建启动类 eureka1
3. 设置application.yml
eureka-server2相同把端口换成10087,注册地址换成10086就行了
2.创建服务提供者userservice
1. pom.xml的配置 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2. 设置application.yml配置文件
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis
username: root
password: 960326
application:
name: userservice
logging:
level:
com.practice:
debug
eureka:
client:
service-url: #eurekaServer 地址
defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
instance:
prefer-ip-address: true #当调用getHostname获取实例的hostname时 返回ip而不是host名称
ip-address: 127.0.0.1 #指定自己的ip信息 不指定的话会自己寻找
lease-expiration-duration-in-seconds: 10 #服务失效时间 默认90秒
lease-renewal-interval-in-seconds: 5 #服务续约时间的间隔,默认30秒
instance-id: ${spring.application.name}:${server.port} #设置id
2.创建启动类,和pojo对象类
@Table(name = "tb_user")
public class User implements Serializable { private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 用户名
private String userName; // 密码
private String password; // 姓名
private String name; // 年龄
private Integer age; // 性别,1男性,2女性
private Integer sex; // 出生日期
private Date birthday; // 创建时间
private Date created; // 更新时间
private Date updated; // 备注
// private String note; // 。。。省略getters和setters
//TODO 需要手动添加getter,setter
}
3.创建controller,service ,mapper
package com.practice.controller; import com.practice.pojo.User;
import com.practice.service.UserService;
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;
import org.springframework.web.bind.annotation.RequestMapping; @RestController
@RequestMapping("user")
public class UserController { @Autowired
private UserService userService; @GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return this.userService.queryById(id);
}
} /**
*设置睡眠是为了测试熔断器
*/
package com.practice.service; import com.practice.mapper.UserMapper;
import com.practice.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class UserService { @Autowired
private UserMapper userMapper;
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public User queryById(Long id) {
Long startTime = System.currentTimeMillis();
int time = (int)(Math.random()*2000+1);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
User user = this.userMapper.selectByPrimaryKey(id);
Long endTime = System.currentTimeMillis();
logger.info("本次查询:{},花费时间为{}ms",id,endTime-startTime);
return user;
}
} /**
*通用mapper的使用,可以动态生成实现子类和查询语言适用于单表查询
*/ package com.practice.mapper; import com.practice.pojo.User;
import tk.mybatis.mapper.common.Mapper; public interface UserMapper extends Mapper<User> {
}
3创建服务消费者cosumer-demo
1.pom.xml配置 需要的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加OkHttp支持 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.</version>
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--Hystrix依赖-->
<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>
2. application.xml的配置
Spring:
application:
name: consumer
eureka:
client:
service-url: #eurekaServer地址
defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
registry-fetch-interval-seconds: 5 #获取更新服务列表 默认时间为30秒 instance:
prefer-ip-address: true #当其它服务获取地址时提供ip而不是hostname
ip-address: 127.0.0.1 #指定自己的ip信息 不指定的话会自己寻找
ribbon: #修改服务负载均衡的分流规则
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机 默认为轮询
ConnectTimeout: 250 # ribbon 连接超时时间
ReadTimeout: 1000 #Ribbon 数据读取超时时间
feign:
hystrix:
enabled: true #开启feign的熔断支持默认关闭
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
logging:
level:
com.consumer:
debug
3. 创建启动类 和pojo对象类
package com; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient
@SpringBootApplication
//@EnableHystrix
@EnableFeignClients
public class Consumer {
// @Bean
// @LoadBalanced //开启负载均衡
// public RestTemplate restTemplate(){
// // 使用OKHTTP客户端,只需注入工厂
// return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
// }
// 因为Feign 中自动集成 Ribbon 负载均衡 所以不需要自定义RestTemplate
public static void main(String[] args) {
SpringApplication.run(Consumer.class); }
}
/**
*属性类型和user-service中相同但是不用加@table之类的注解
*/
public class User { private static final long serialVersionUID = 1L; private Long id; // 用户名
private String userName; // 密码
private String password; // 姓名
private String name; // 年龄
private Integer age; // 性别,1男性,2女性
private Integer sex; // 出生日期
private Date birthday; // 创建时间
private Date created; // 更新时间
private Date updated; //TODO 需要手动添加getter,setter
}
4. 创建 controller,service,config (dao是测试hystrix时创建的,feign中支持熔断所以不用创建)
package com.consumer.controller; import com.consumer.pojo.User;
import com.consumer.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController
@RequestMapping("consume")
public class ConsumerController {
@Autowired
private UserService userService; @GetMapping
public List<User> consume(@RequestParam("ids")List<Long> ids){
return this.userService.queryUserByIds(ids);
}
} package com.consumer.service; import com.consumer.config.UserFeignClient;
import com.consumer.config.impl.UserFeignClientImpl;
import com.consumer.dao.UserDao;
import com.consumer.pojo.User;
//import com.netflix.discovery.DiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import java.util.ArrayList;
import java.util.List; @Service
public class UserService { /**
* 根据服务名称,获取服务实例
* */ @Autowired
private UserFeignClient userFeignClient;
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>(); ids.forEach(id ->{
users.add(userFeignClient.queryById(id));
/* try {
Thread.sleep(500);
线程睡眠用于测试可以删除
} catch (InterruptedException e) {
e.printStackTrace();
}*/
});
return users;
} } package com.consumer.config; import com.consumer.config.impl.FeignConfig;
import com.consumer.config.impl.UserFeignClientImpl;
import com.consumer.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "userservice",fallback = UserFeignClientImpl.class,configuration = FeignConfig.class) public interface UserFeignClient {
@GetMapping("/user/{id}")
public User queryById(@PathVariable("id") Long id);
} package com.consumer.config.impl; import com.consumer.config.UserFeignClient;
import com.consumer.pojo.User;
import org.springframework.stereotype.Component; @Component
public class UserFeignClientImpl implements UserFeignClient { @Override
public User queryById(Long id) {
User user = new User();
user.setId(id);
user.setName("请求超时,请稍后重试--feign");
return user;
}
} package com.consumer.config.impl; import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* 编写配置类定义feign的日志级别 feign支持四种级别
* - NONE:不记录任何日志信息,这是默认值。
* - BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
* - HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
* - FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
4. 创建zuul网关
1.pom.xml中的依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2. application.yml
server:
port: 10010
spring:
application:
name: gateway
zuul:
routes:
userservice: userservice/** #简便方式
prefix: /api #添加路由前缀
# path: /userservice/** #这是映射路径
# serviceId: userservice #指定服务名称
# url: http://127.0.0.1:8081 映射路径对应的实际url地址
eureka:
client:
registry-fetch-interval-seconds: 5 #循环获取服务列表
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127:0.0.1
3. 创建启动器
package com.zuul; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy //开启网关功能
public class Zuul {
public static void main(String[] args) {
SpringApplication.run(Zuul.class);
}
}
测试成功的页面:
认识并学会springCloud的使用的更多相关文章
- SpringCloud(二)- 服务注册与发现Eureka
离上一篇微服务的基本概念已经过去了几个月,在写那篇博客之前,自己还并未真正的使用微服务架构,很多理解还存在概念上.后面换了公司,新公司既用了SpringCloud也用了Dubbo+Zookeeper, ...
- SpringCloud 入门知识篇
SpringCloud 入门 springcloud 学习 7天学会springcloud 教程 https://www.cnblogs.com/skyblog/category/738524.htm ...
- Spring Boot初识
今天准备开一个新系列springboot,springboot结束后会更新springcloud,想要学会springcloud先学springboot吧.以后springboot和hadoop轮流更 ...
- 如何学习SpringCloud?(SpringCloud模板)
前言 对于SpringCloud来说(下面简称SC),现在网上已经有很多教程写的非常详细,因为SC的组件特别多,虽然不是所有组件都需要用到,但是学习的时候我们都需要去学习和了解.所以我想如果再写把每一 ...
- SpringCloud笔记四:Ribbon
目录 什么是Ribbon? Ribbon的配置 Maven引入 开启注解 Ribbon负载均衡 新建provider8002和8003 Ribbon核心组件IRule Ribbon自定义 什么是Rib ...
- SpringCloud教程 | 第一篇: 服务的注册与发现
一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...
- 使用Java类加载SpringBoot、SpringCloud配置文件
我们都知道平常在使用SpringBoot和SpringCloud的时候,如果需要加载一两个配置文件的话我们通常使用@Value("${属性名称}")注解去加载.但是如果配置文件属性 ...
- 每天学点SpringCloud(四):Feign的使用及自定义配置
Feign:SpringCloud的官网对它的定义是这样的: 是一个声明式的Web服务客户端.它支持Feign本身的注解.JAX-RS注解以及SpringMVC的注解.Spring Cloud集成Ri ...
- SpringCloud学习6-如何创建一个服务消费者consumer
上一节如何创建一个服务提供者provider已经启动了一个provider的server,提供用户信息查询接口.接下来,我们启动另一个provider,由于是同一台机器本地测试,我们换一个端口 --s ...
随机推荐
- 2019牛客暑期多校训练营(第一场)H 线性基+计算贡献
题意 给n个整数,求满足子集异或和为0的子集大小之和. 分析 将问题转化为求每个元素的贡献次数之和. 先对n个数求线性基,设线性基大小为r,即插入线性基的数字个数为r,可以分别计算线性基内数的贡献和线 ...
- 使用A* Pathfinding Project的一些心得
最近在游戏开发中要做寻路.首选果断就是Unity3D自带的寻路啦.方便稳定,基本功能都能满足.我们的需求也不复杂,就是一个英雄在不同的地图中探索.但是介于一个比较恶心的问题,果断放弃了它.所以,说A* ...
- Java集合框架系列大纲
###Java集合框架之简述 Java集合框架之Collection Java集合框架之Iterator Java集合框架之HashSet Java集合框架之TreeSet Java集合框架之Link ...
- Latex中 summation前后距离的设置
use \hspace ,eg., \hspace{-.1cm} before and after summation to stop violation of margin. 比如下面一段公式代码 ...
- JavaWeb_(Struts2框架)使用Struts框架实现用户的登陆
JavaWeb_(Struts2框架)使用Servlet实现用户的登陆 传送门 JavaWeb_(Struts2框架)Servlet与Struts区别 传送门 MySQL数据库中存在Gary用户,密码 ...
- 深入使用Vue + TS
深入使用TS 支持 render jsx 写法 这里一共分两步 首先得先让 vue 支持 jsx 写法 再让 vue 中的 ts 支持 jsx 写法 让 vue 支持 jsx 按照官方做法,安装Bab ...
- RabbitMQ MQTT协议和AMQP协议
RabbitMQ MQTT协议和AMQP协议 1 序言... 1 1.1 RabbitMq结构... 1 1.2 RabbitMq消息接收... 4 1.3 Ex ...
- BZOJ1706奶牛接力跑
这个东西思路还是不错的. 解法就是把矩阵幂的加法改成取min,乘法改成加法就好,和floyed是一样的.这样的话,矩阵操作一次就相当于松弛了一次最短路. 建矩阵的过程也比较简单,可以离散化,当然下面有 ...
- leetcode-hard-array-238. Product of Array Except Self-NO
mycode 99.47% class Solution(object): def productExceptSelf(self, nums): """ :type ...
- 浅析history hack、心血漏洞、CSS欺骗、SQL注入与CSRF攻击
漏洞产生的原因主要有系统机制和编码规范两方面,由于网络协议的开放性,目前以 Web 漏洞居多 关于系统机制漏洞的典型有JavaScript/CSS history hack,而编码规范方面的漏洞典型有 ...