需求一:
-
基於spring boot搭建商家服務,商品服務
-
搭建Eureka server 註冊中心
-
用戶服務
- 根據ID查詢商家信息
- 添加商品信息(調用商品服務)
-
商品服務
-
添加商品信息到MySQL
{ "title":"榮耀X10 5G雙模 麒麟820 4300mAh續航 4000萬高感光影像系統 6.63英寸升降全面屏 全網通6GB+128GB 競速藍", "price":2199.00, "saleNum":6521, "categoryName":"手機", "brandName":"華爲" }
-
-
使用Hystix 對添加商品進行降級處理
搭建環境
- 數據庫
鏈接:https://pan.baidu.com/s/1v0y5Yc6RiPKtcPsto6F9Ew
提取碼:18v8
-
創建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> <groupId>com.itheima</groupId> <artifactId>fuxi_parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!--spring boot 環境 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <!--spring cloud 版本--> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> </properties> <!--引入Spring Cloud 依賴--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
-
創建公用的模塊,封裝JavaBean
注意: 如果需要使用流來傳輸對象,需要實現IO包的序列化接口。一般可以默認加上。
搭建註冊中心
步驟:
① 創建 eureka-server 模塊
<!-- 繼承父工程 -->
<parent>
<artifactId>spring-cloud-parent</artifactId>
<groupId>com.itheima</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
② 引入 SpringCloud 和 euraka-server 相關依賴
<dependencies>
<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-server</artifactId>
</dependency>
</dependencies>
③ 完成 Eureka Server 相關配置
server:
port: 8761
# eureka 配置
# eureka 一共有4部分 配置
# 1. dashboard:eureka的web控制檯配置
# 2. server:eureka的服務端配置
# 3. client:eureka的客戶端配置
# 4. instance:eureka的實例配置
eureka:
instance:
hostname: localhost # 主機名
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服務端地址,將來客戶端使用該地址和eureka進行通信
register-with-eureka: false # 是否將自己的路徑 註冊到eureka上。eureka server 不需要的,eureka provider client 需要
fetch-registry: false # 是否需要從eureka中抓取路徑。eureka server 不需要的,eureka consumer client 需要
server:
enable-self-preservation: false # 關閉自我保護機制
eviction-interval-timer-in-ms: 3000 # 檢查服務的時間間隔
④ 啓動該模塊
@SpringBootApplication
// 啓用EurekaServer
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
搭建商家服務
-
創建fuxi_seller模塊
-
基於spring boot搭建SSM模塊
-
添加依賴,配置pom.xml
<dependencies> <dependency> <groupId>com.itheima</groupId> <artifactId>fuxi_pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <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> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
-
編寫啓動類
@SpringBootApplication @EnableEurekaClient public class SellerApp { public static void main(String[] args) { SpringApplication.run(SellerApp.class,args); } }
-
編寫配置文件
server: port: 9001 eureka: instance: hostname: localhost # 主機名 client: service-url: defaultZone: http://localhost:8761/eureka # eureka服務端地址,將來客戶端使用該地址和eureka進行通信 spring: application: name: seller # 設置當前應用的名稱。將來會在eureka中Application顯示。將來需要使用該名稱來獲取路徑 datasource: url: jdbc:mysql:///db_user?serverTimezone=Asia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
-
根據ID查詢商家信息
-
dao
@Mapper public interface SellerMapper { @Select("select * from seller where id =#{id}") public Seller findById(Integer id); }
-
service
@Service public class SellerService { @Autowired SellerMapper sellerMapper; public Seller findSellerById(Integer id){ return sellerMapper.findById(id); } }
-
controller
@RestController @RequestMapping("/seller") public class SellerController { @Autowired SellerService sellerService; @GetMapping("/{id}") public Seller findSellerById(@PathVariable("id") Integer id){ return sellerService.findSellerById(id); } }
-
測試
搭建商品服務
-
創建fuxi_goods模塊
-
基於spring boot搭建SSM模塊
-
添加依賴,配置pom.xml
<dependencies> <dependency> <groupId>com.itheima</groupId> <artifactId>fuxi_pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <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> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
-
編寫啓動類
@SpringBootApplication @EnableEurekaClient public class GoodsApp { public static void main(String[] args) { SpringApplication.run(GoodsApp.class,args); } }
-
編寫配置文件
server: port: 9002 eureka: instance: hostname: localhost # 主機名 client: service-url: defaultZone: http://localhost:8761/eureka # eureka服務端地址,將來客戶端使用該地址和eureka進行通信 spring: application: name: goods # 設置當前應用的名稱。將來會在eureka中Application顯示。將來需要使用該名稱來獲取路徑 datasource: url: jdbc:mysql:///db_goods?serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
-
提供方-商品添加
-
dao
@Mapper public interface GoodsMapper { @Insert(" INSERT INTO `goods`(`title`,`price`,`stock`,`saleNum`,`createTime`,`categoryName`,`brandName`,`spec`,`seller`,`company`) \n" + "VALUES (\n" + "#{title},\n" + "#{price},\n" + "NULL,\n" + "#{saleNum},\n" + "#{createTime},\n" + "#{categoryName},\n" + "#{brandName},\n" + "#{specStr},\n" + "#{seller},\n" + "#{company}\n" + ") ") public void saveGoods(Goods goods); }
-
service
@Service public class GoodsService { @Autowired GoodsMapper goodsMapper; public void saveGoods(Goods goods){ goodsMapper.saveGoods(goods); } }
-
controller
@RestController @RequestMapping("/goods") public class GoodsController { @Autowired GoodsService goodsService; @PostMapping("/save") public Reslut saveGoods(@RequestBody Goods goods){ try{ goodsService.saveGoods(goods); return new Reslut(true,"商品添加成功!"); }catch (Exception e){ e.printStackTrace(); return new Reslut(false,"系統錯誤,添加失敗!"); } } }
-
測試
{ "title":"榮耀X10 5G雙模 麒麟820 4300mAh續航 4000萬高感光影像系統 6.63英寸升降全面屏 全網通6GB+128GB 競速藍", "price":2199.00, "saleNum":6521, "categoryName":"手機", "brandName":"華爲" }
調用方-商品添加
-
添加feign依賴,開啓開關
<!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
啓動feign
@SpringBootApplication @EnableEurekaClient @EnableFeignClients //開啓Feign的功能 public class SellerApp { public static void main(String[] args) { SpringApplication.run(SellerApp.class,args); } }
-
配置rest Template對象
@LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
-
編寫Feign客戶端,配置
@FeignClient(value = "goods") public interface GoodsFeign { @PostMapping("/goods/save") public Reslut saveGoods(@RequestBody Goods goods); }
-
再controller中,調用feign客戶端
@Autowired GoodsFeign goodsFeign; @PostMapping("/saveGoods/{sellerId}") public Reslut saveGoods(@PathVariable("sellerId") Integer sellerId,@RequestBody Goods goods){ Seller seller = sellerService.findSellerById(sellerId); goods.setSeller(seller.getSeller()); goods.setCompany(seller.getCompany()); goods.setCreateTime(new Date()); goods.setSpecStr("{\"機身內存\":\"16G\",\"網絡\":\"聯通3G\"}"); Reslut reslut = goodsFeign.saveGoods(goods); return reslut; }
-
測試
{ "title":"榮耀X10 5G雙模 麒麟820 4300mAh續航 4000萬高感光影像系統 6.63英寸升降全面屏 全網通6GB+128GB 競速藍", "price":2199.00, "saleNum":6521, "categoryName":"手機", "brandName":"華爲" }
-
遇到一個啓動異常,缺少 spring-cloud-starter-netflix-ribbon 修復
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
Hystix 降級處理-服務提供方
操作步驟:
-
在服務提供方,引入 hystrix 依賴
<!-- hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
-
在啓動類上開啓Hystrix功能:@EnableCircuitBreaker
/** * 啓動類 */ @EnableEurekaClient @SpringBootApplication @EnableCircuitBreaker // 開啓Hystrix功能 public class GoodsApp {
-
定義降級方法
/** * 定義降級方法: * 1. 方法的返回值需要和原方法一樣 * 2. 方法的參數需要和原方法一樣 * 3. 就是隻有方法名不同 */ public Reslut saveGoods_fallback(@RequestBody Goods goods){ return new Reslut(false,"服務方降級!"); }
-
使用 @HystrixCommand 註解配置降級方法
@PostMapping("/save") @HystrixCommand(fallbackMethod = "saveGoods_fallback") public Reslut saveGoods(@RequestBody Goods goods){ if(goods.getPrice()<100){ throw new RuntimeException("太便宜了,不能添加!"); } goodsService.saveGoods(goods); return new Reslut(true,"商品添加成功!"); } public Reslut saveGoods_fallback(@RequestBody Goods goods){ return new Reslut(false,"服務方降級!"); }
Hystix 降級處理-調用方
操作步驟:
-
feign 組件已經集成了 hystrix 組件。
-
在application.yml中配置開啓 feign.hystrix.enabled = true
# 開啓feign對hystrix的支持 feign: hystrix: enabled: true
-
定義feign 調用接口實現類,複寫方法,即 降級方法
/** * Feign 客戶端的降級處理類 * 1. 定義類 實現 Feign 客戶端接口 * 2. 使用@Component註解將該類的Bean加入SpringIOC容器 */ @Component public class GoodsFeignClientFallback implements GoodsFeignClient { @Override public Goods findGoodsById(int id) { Goods goods = new Goods(); goods.setTitle("又被降級了~~~"); return goods; } }
-
在 @FeignClient 註解中使用 fallback 屬性設置降級處理類。
@FeignClient(value = "HYSTRIX-PROVIDER",fallback = GoodsFeignClientFallback.class) public interface GoodsFeignClient { @GetMapping("/goods/findOne/{id}") public Goods findGoodsById(@PathVariable("id") int id); }
需求二:
- 基於spring boot搭建商品搜索服務
- 搜索服務
- 向ES添加商品信息
- 商品關鍵字搜索(儘量符合用戶的使用,參考京東)
- 商品服務發送消息,搜索服務接收消息完成MYSQL添加商品後自動同步到ES
商品服務發送消息
-
導入amqp的起步依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
-
在application.yml配置mq的連接信息
rabbitmq: host: 192.168.200.129 port: 5672 virtual-host: /itcast username: heima password: heima
-
配置RabbitMQConfig類
- 創建queue
- 創建Exchange
- 綁定
@Configuration public class RabbitMQConfig { //交換機名稱 public static final String ITEM_TOPIC_EXCHANGE = "goods_topic_exchange"; //隊列名稱 public static final String ITEM_QUEUE = "goods_queue"; //聲明交換機 @Bean("itemTopicExchange") public Exchange topicExchange(){ return ExchangeBuilder.topicExchange(ITEM_TOPIC_EXCHANGE).durable(true).build(); } //聲明隊列 @Bean("itemQueue") public Queue itemQueue(){ return QueueBuilder.durable(ITEM_QUEUE).build(); } //綁定隊列和交換機 @Bean public Binding itemQueueExchange(@Qualifier("itemQueue") Queue queue, @Qualifier("itemTopicExchange") Exchange exchange){ return BindingBuilder.bind(queue).to(exchange).with("goods.#").noargs(); } }
-
GoodsService 注入RabbitTempalte,發送消息
@Autowired
RabbitTemplate rabbitTemplate;
public void saveGoods(Goods goods){
//將goods信息存入mysql
goodsMapper.saveGoods(goods);
//準備消息內容
String specStr = goods.getSpecStr();
Map spec = JSON.parseObject(specStr,Map.class);
goods.setSpec(spec);
String data = JSON.toJSONString(goods);
System.out.println(data);
//發送消息
rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE,"goods.save",data);
}
搭建搜索服務
-
添加依賴(web,amqp,es相關依賴)
<dependencies> <dependency> <groupId>com.itheima</groupId> <artifactId>fuxi_pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!--引入es的座標--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.4.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.4.0</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.4.0</version> </dependency> </dependencies>
-
啓動類
@SpringBootApplication @EnableEurekaClient public class SearchApp { public static void main(String[] args) { SpringApplication.run(SearchApp.class,args); } }
-
配置文件
application.yml
server:
port: 9003
eureka:
instance:
hostname: localhost # 主機名
client:
service-url:
defaultZone: http://localhost:8761/eureka # eureka服務端地址,將來客戶端使用該地址和eureka進行通信
spring:
application:
name: search # 設置當前應用的名稱。將來會在eureka中Application顯示。將來需要使用該名稱來獲取路徑
rabbitmq:
host: 192.168.200.129
port: 5672
virtual-host: /itcast
username: heima
password: heima
elasticsearch:
host: 192.168.200.129
port: 9200
搜索服務接收消息
- 複製消息生產者的配置類
-
編寫消息的監聽類
@Component public class GoodsListener { @RabbitListener(queues = RabbitMQConfig.ITEM_QUEUE) public void goodsListener(String jsonGoods){ System.out.println("接收到了消息:"+jsonGoods); } }
-
測試消息
搜索服務添加ES文檔
-
搭建ES環境,創建索引和映射
PUT fuxi_goods { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_smart" }, "price": { "type": "double" }, "createTime": { "type": "date" }, "categoryName": { "type": "keyword" }, "brandName": { "type": "keyword" }, "spec": { "type": "object" }, "saleNum": { "type": "integer" }, "stock": { "type": "integer" }, "seller": { "type": "keyword" }, "company": { "type": "keyword" } } } }
-
創建ES 高級客戶端配置類
@Configuration @ConfigurationProperties(prefix="elasticsearch") public class ElasticSearchConfig { private String host; private int port; public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } @Bean public RestHighLevelClient client(){ return new RestHighLevelClient(RestClient.builder( new HttpHost(host,port,"http") )); } }
-
編寫service保存文檔
@Service public class GoodsESService { @Autowired RestHighLevelClient client; //添加ES文檔 public void saveGoods(String jsonGoods) throws IOException { Goods goods = JSON.parseObject(jsonGoods,Goods.class); IndexRequest request=new IndexRequest("itcast").id(goods.getId()+"").source(jsonGoods, XContentType.JSON); IndexResponse response = client.index(request, RequestOptions.DEFAULT); } }
-
在listener進行調用
@Component public class GoodsListener { @Autowired GoodsESService service; @RabbitListener(queues = RabbitMQConfig.ITEM_QUEUE) public void goodsListener(String jsonGoods){ System.out.println("接收到了消息:"+jsonGoods); //添加文檔 try { service.saveGoods(jsonGoods); } catch (IOException e) { e.printStackTrace(); } } }
-
測試
問題: 消息內容中goods沒有id,ES文檔操作變成了覆蓋.
解決: 消息中應該將goods id添加到信息中,goods id是由mysql自增長,所以在mapper中insert中配置返回主鍵。
GoodsMapper
@Options(keyProperty = "id",useGeneratedKeys = true) public void saveGoods(Goods goods);
搜索服務商品查詢
-
需求分析
- 沒有輸入查詢關鍵字 keyword ,不進行查詢
- keyword ,使用query String進行查詢,從title,brand,category進行查詢,操作OR
- 添加brand條件 ,filter
- 添加價格 最大值最小值 price=1000-2000
-
設計
參數 Map
返回 List
-
編寫service,商品查詢
/* 1. 沒有輸入查詢關鍵字 keyword ,不進行查詢 2. keyword ,使用query String進行查詢,從title,brand,category進行查詢,操作OR 3. 添加brand條件 ,filter 4. 添加價格 最大值最小值 price=1000-2000 */ //商品查詢 public List<Goods> findGoods(Map<String,String> param) throws IOException { SearchRequest searchRequest = new SearchRequest("fuxi_goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); //1.構建boolQuery BoolQueryBuilder query = QueryBuilders.boolQuery(); //沒有輸入查詢關鍵字 keyword ,不進行查詢 if(param==null && StringUtils.isBlank(param.get("keyword"))){ return new ArrayList<>(); } //keyword ,使用query String進行查詢,從title,brand,category進行查詢,操作OR QueryStringQueryBuilder qsquery = QueryBuilders.queryStringQuery(param.get("keyword")) .field("title").field("categoryName").field("brandName") .defaultOperator(Operator.OR); query.must(qsquery); //添加brand條件 ,filter if(StringUtils.isNotBlank(param.get("brand"))) { QueryBuilder termQuery = QueryBuilders.termQuery("brandName", param.get("brand")); query.filter(termQuery); } //查詢價格在:2000-3000 if(StringUtils.isNotBlank(param.get("price"))) { String[] ps = param.get("price").split("-"); QueryBuilder rangeQuery = QueryBuilders.rangeQuery("price"); ((RangeQueryBuilder) rangeQuery).gte(ps[0]); ((RangeQueryBuilder) rangeQuery).lte(ps[1]); query.filter(rangeQuery); } //3.使用boolQuery連接 sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //獲取記錄數 long value = searchHits.getTotalHits().value; System.out.println("總記錄數:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); //轉爲java Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } return goodsList; }
-
controller
@RestController public class ESGoodsController { @Autowired GoodsESService goodsESService; @PostMapping("/search") public List<Goods> findGoods(@RequestBody Map<String,String> param){ List<Goods> list = null; try { list = goodsESService.findGoods(param); } catch (IOException e) { e.printStackTrace(); } return list; } }
-
測試
在商家服務中調用商品搜索
- 編寫feign客戶端
- 遠程調用搜索服務
作爲作業
需求三:
- 搭建網關gateway,配置路由
- 搭建註冊中心 config server
- 將配置信息上傳上gitee
- 將商家服務,商品服務,搜索服務的信息配置到配置中心
- 配置bus一鍵刷新
- 使用docker部署商家服務,商品服務,搜索服務
網關的配置
操作步驟:
-
搭建網關模塊,導入資料中的初始化代碼
其實就是創建一個最基本的spring cloud模塊。
-
引入依賴:starter-gateway
<dependencies> <!--引入gateway 網關--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
-
編寫啓動類,無特殊操作
@SpringBootApplication @EnableEurekaClient public class GatewayApp { public static void main(String[] args) { SpringApplication.run(GatewayApp.class,args); } }
-
編寫配置文件
server: port: 80 spring: application: name: fuxi-gateway-server cloud: # 網關配置 gateway: # 路由配置:轉發規則 routes: #集合。 # id: 唯一標識。默認是一個UUID # uri: 轉發路徑 # predicates: 條件,用於請求網關路徑的匹配規則 - id: gateway-seller uri: lb://seller predicates: - Path=/seller/** - id: gateway-goods uri: lb://goods predicates: - Path=/goods/** eureka: client: service-url: defaultZone: http://localhost:8761/eureka
-
測試
配置中心服務
搭建配置中心服務
- 準備環境,創建git倉庫
-
在本地克隆git倉庫,管理配置文件
應該配置在註冊中心的信息,除了註冊中心意外的信息,都可以通過配置中心進行管理。
3. 搭建配置中心
-
添加依賴
<dependencies> <!-- config-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
-
啓動類
@SpringBootApplication @EnableEurekaClient @EnableConfigServer // 啓用config server功能 public class ConfigServerApp { public static void main(String[] args) { SpringApplication.run(ConfigServerApp.class,args); } }
-
配置文件
server: port: 9527 spring: application: name: config-server # spring cloud config cloud: config: server: # git 的 遠程倉庫地址 git: uri: https://gitee.com/easyitcast/fuxi_config.git label: master # 分支配置 eureka: client: service-url: defaultZone: http://localhost:8761/eureka
-
測試
http://localhost:9527/master/seller-dev.yml
配置中心客戶端
-
在客戶端應用 fuxi_seller添加依賴
<!--config client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
-
在客戶端模塊中,添加配置文件 bootstrap.yml
# 配置config-server地址 # 配置獲得配置文件的名稱等信息 spring: cloud: config: # 配置config-server地址 # uri: http://localhost:9527 # 配置獲得配置文件的名稱等信息 name: seller # 文件名 profile: dev # profile指定, seller-dev.yml label: master # 分支 discovery: enabled: true service-id: config-server eureka: client: service-url: defaultZone: http://localhost:8761/eureka
BUS全局刷新
熱部署,fuxi_seller配置文件修改後無需重啓。
config client刷新操作步驟:
-
在 config 客戶端引入 actuator 依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
獲取配置信息類上,添加 @RefreshScope 註解
@RestController @RequestMapping("/seller") @RefreshScope // 開啓刷新功能 public class SellerController {
-
添加配置 bootstrap.yml
management.endpoints.web.exposure.include: refreshmanagement: endpoints: web: exposure: include: '*' # 暴漏的endpoint,*表示所有
-
使用curl工具發送post請求
curl -X POST http://localhost:9001/actuator/refresh
通過BUS進行統一部署
-
分別在 fuxi_config_server 和 fuxi_seller中引入 bus依賴:bus-amqp
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- bus --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
-
分別在 config-server 和 config-client中配置 RabbitMQ(3個模塊都配置)
bootstrap.yml和config-server的application.yml
#配置rabbitmq信息 rabbitmq: host: 192.168.200.129 port: 5672 username: guest password: guest virtual-host: /
注意位置:是spring節點的屬性
-
在config-server中設置暴露監控斷點:bus-refresh
是通過actuator來實現,添加對actuator的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
暴漏endpoint的配置
# 暴露bus的刷新端點 management: endpoints: web: exposure: include: 'bus-refresh'
-
啓動測試
訪問的是config-server的刷新節點:
curl -X POST http://localhost:9527/actuator/bus-refresh
項目部署上線
-
項目打包
springboot項目打jar包,添加打包插件。
需要打包的工程中的添加
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
執行maven打包命令 package
-
從target中,複製打包好的jar,然後進行運行
java -jar fuxi_seller-1.0-SNAPSHOT.jar
問題:
打包失敗,找不到pojo工程。
解決方法: clean,並install應用。
-
-
jar包部署
-
docker容器部署
springboot應用,要連接docker中運行的mysql容器,那麼數據源的配置應該使用 宿主機的IP和映射的端口。
-
dockfile製作鏡像
-
修改數據源信息,並打包應用。
-
編寫dockerfile文件
springboot_dockerfile
FROM java:8 MAINTAINER itheima<[email protected]> ADD fuxi_seller-1.0-SNAPSHOT.jar app.jar CMD java -jar app.jar
-
3. 將打包好的jar和springboot_dockerfile上傳到服務器上
在虛擬機中創建目錄
```shell
cd ~
mkdir apps
cd apps
```
CRT中打開上傳fstp.alt+p
```shell
#在windows下,進入有jar和dockfile文件的目錄(不能帶中文)
lcd C:\Users\admin\Desktop\apps
#進服務器,進入上面新建的apps目錄中
cd apps
#上傳文件
put fuxi_seller-1.0-SNAPSHOT.jar
put springboot_dockerfile
```
4. 根據上傳的文件創建docker鏡像
```shell
docker build -f ./springboot_dockerfile -t itheima_app:1 .
```
5. 根據鏡像啓動容器
```sh
docker run -id --name=c_springboot -p 9001:9001 itheima_app:1
```
6. 測試