
Showing posts with label docker. Show all posts
Showing posts with label docker. Show all posts
Sunday, October 15, 2023
Saturday, July 11, 2020
Friday, July 10, 2020
Thursday, July 9, 2020
Tuesday, July 7, 2020
Tuesday, May 26, 2020
Thursday, January 2, 2020
Spring Cloud 微服務入門 (十二) restemplete 多層服務呼叫 docker - compose 構建 (二)
目前架構

可以看到我們下面 服務好像有固定的數據庫可能是集群或是什麼
在前面的學習好像沒看到更複雜的調用,分布式很多問題,像是數據不同步,光是鎖就有一大堆,就以認證中心設計成微服務的話,
資料庫就會變成多個,這樣就不能判斷你到底是到底在哪一台調用,而出現你有雙重的登入資料緩存在分散的資料庫解決方式可能有
一 分布式鎖
二共用同一個資料庫
這部分先以後有空再弄,目前就是先拓展為多層調用,今天是來實現多層的話服務溝通使用
restemplate 去溝通。

可以看到我們下面 服務好像有固定的數據庫可能是集群或是什麼
在前面的學習好像沒看到更複雜的調用,分布式很多問題,像是數據不同步,光是鎖就有一大堆,就以認證中心設計成微服務的話,
資料庫就會變成多個,這樣就不能判斷你到底是到底在哪一台調用,而出現你有雙重的登入資料緩存在分散的資料庫解決方式可能有
一 分布式鎖
二共用同一個資料庫
這部分先以後有空再弄,目前就是先拓展為多層調用,今天是來實現多層的話服務溝通使用
restemplate 去溝通。
分析
我們把服務擴展為兩層一下
也就是我們要關注的
好吧開始
目前我們的
service 已經有 5個
我們要來 新增了 2 個 也就是模擬第四層
一個是
EurekaServiceFeignConsumer2
EurekaServiceFeignProvider3
其中兩個各別都是從 也就是模擬第三層
EurekaServiceFeignProvider
EurekaServiceFeignConsumer
複製出來
來看一下代碼
那麼我們原本的服務會變怎樣呢
EurekaServiceFeignProvider1
EurekaServiceFeignProvider2
要調用我們的
EurekaServiceFeignProvider3
所以調用順序就是
Zuul - > Consumer1 - > Provider1 or Provider2 -> Consumer2 > Provider3
所以先針對我們的 Consumer1 來修改
我們把服務擴展為兩層一下
也就是我們要關注的

好吧開始
目前我們的
service 已經有 5個
我們要來 新增了 2 個 也就是模擬第四層
一個是
EurekaServiceFeignConsumer2
EurekaServiceFeignProvider3
EurekaServiceFeignProvider
EurekaServiceFeignConsumer
複製出來
來看一下代碼
那麼我們原本的服務會變怎樣呢
EurekaServiceFeignProvider1
EurekaServiceFeignProvider2
要調用我們的
EurekaServiceFeignProvider3
Zuul - > Consumer1 - > Provider1 or Provider2 -> Consumer2 > Provider3
所以先針對我們的 Consumer1 來修改
多層服務的呼叫方式
調用服務三 但是要取得服務四 的 response 才算調用完成
那就變成
要完成server3 呼叫就要
server3 -> server 4
多經過一層 server 4 這樣的話 可能會覺得我那就用我們上次
doget
doposs
這兩種方法就好了那有沒有更優雅的方式呢有的歐,
spring 幫我們把這些東西再往上封裝了一層也就是 restemplate
(如果你想用到更複雜的調用你就自己從底層慢慢研究了)
那就變成
要完成server3 呼叫就要
server3 -> server 4
多經過一層 server 4 這樣的話 可能會覺得我那就用我們上次
doget
doposs
這兩種方法就好了那有沒有更優雅的方式呢有的歐,
spring 幫我們把這些東西再往上封裝了一層也就是 restemplate
(如果你想用到更複雜的調用你就自己從底層慢慢研究了)
Consumer1 Controller
我們新增了
@GetMapping("/helloEX/{id}/{id2}")
public String helloEX(@PathVariable(name="id") Integer employeeId,@PathVariable(name="id2") Integer employeeId2) {
System.out.print(employeeId2);
String message = homeClient.home2(employeeId,employeeId2);
logger.info("[eureka-fegin][ConsumerController][hello], message={}", message);
// log.info("[eureka-ribbon][EurekaRibbonConntroller][syaHello], message={}", message);
return message ;
好了之後 我們要看要調用哪一層就是我們的
@GetMapping("/helloEX/{id}/{id2}")
public String helloEX(@PathVariable(name="id") Integer employeeId,@PathVariable(name="id2") Integer employeeId2) {
System.out.print(employeeId2);
String message = homeClient.home2(employeeId,employeeId2);
logger.info("[eureka-fegin][ConsumerController][hello], message={}", message);
// log.info("[eureka-ribbon][EurekaRibbonConntroller][syaHello], message={}", message);
return message ;
Consumer1 homeClient
@GetMapping("/ep1")
public String home2(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) ;
@GetMapping("/ep1")
public String home2(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) ;
Provider 1 or 2
這邊就要稍微用到前面的技巧了
我們知道有 resttemplete 有可以去跟我們 Eureka 去要我們已經註冊的節點的伺服器名字
整體調用在最下面
https://openhome.cc/Gossip/Spring/RestTemplate.html
https://www.jianshu.com/p/462790156554
我們用到比較關鍵的是
預設的 restemplete 是沒有辦法呼叫負載平衡的,有印象的話在前幾天用過
SPRING CLOUD 微服務入門 (三) EUREKA + CONSUMER (FEIGN) 調用 SERVICE
在這邊的話我們把 restemplete 注入一個有 loadblance 特性
https://blog.csdn.net/qq_18416057/article/details/79432504
這邊說的蠻清楚的 不過少了一些東西
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
總而言之就是讓我們的 restemplete有可以 去 訪問 Eureka 的能力
我們知道有 resttemplete 有可以去跟我們 Eureka 去要我們已經註冊的節點的伺服器名字
整體調用在最下面
https://www.jianshu.com/p/462790156554
我們用到比較關鍵的是
預設的 restemplete 是沒有辦法呼叫負載平衡的,有印象的話在前幾天用過
SPRING CLOUD 微服務入門 (三) EUREKA + CONSUMER (FEIGN) 調用 SERVICE
https://blog.csdn.net/qq_18416057/article/details/79432504
這邊說的蠻清楚的 不過少了一些東西
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
配置 provider
application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
register-with-eureka : true <====就是這行 讓我們的 的 服務可以去請求其他已經註冊的伺服器
那麼現在我們的 restemplete loadblance 特性
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
register-with-eureka : true <====就是這行 讓我們的 的 服務可以去請求其他已經註冊的伺服器
細看 Provider
這邊要注意要跟我們的
Consumer1 homeClient 裡面的 method
相對應,這邊可以看到我們對伺服器的 ip已經不是像我們之前的在寫註冊中心那樣直接doget dopost 去呼叫,restemplete ,當然也可以用這種方式去呼叫我們的註冊中心,只不過,有空再寫好了這邊做兩個範例。
@GetMapping("/ep1")
public String home2(@RequestParam (value="id", required = false) final Integer employeeId,@RequestParam (value="id2", required = false) final Integer employeeId2) {
final String message = "Hello world" + port+ employeeId+employeeId2;
logger.info("[eureka-provide][EurekaServiceProviderApplication][home], message={}", message);
// restTemplate = new RestTemplate();
final String fooResourceUrl = "http://feign-consumer2";
final ResponseEntity<String> response = restTemplate.getForEntity(
fooResourceUrl + "/hello2/" + employeeId.toString() + "/" + employeeId2.toString(), String.class);
//assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
System.out.println(response.getStatusCode().toString()+(HttpStatus.OK).toString());
System.out.println(response.getBody()+"test");
return response.getBody();
}
好了之後複製到 Provider2 兩個 Controller 一樣。
Consumer1 homeClient 裡面的 method
相對應,這邊可以看到我們對伺服器的 ip已經不是像我們之前的在寫註冊中心那樣直接doget dopost 去呼叫,restemplete ,當然也可以用這種方式去呼叫我們的註冊中心,只不過,有空再寫好了這邊做兩個範例。
@GetMapping("/ep1")
public String home2(@RequestParam (value="id", required = false) final Integer employeeId,@RequestParam (value="id2", required = false) final Integer employeeId2) {
final String message = "Hello world" + port+ employeeId+employeeId2;
logger.info("[eureka-provide][EurekaServiceProviderApplication][home], message={}", message);
// restTemplate = new RestTemplate();
final String fooResourceUrl = "http://feign-consumer2";
final ResponseEntity<String> response = restTemplate.getForEntity(
fooResourceUrl + "/hello2/" + employeeId.toString() + "/" + employeeId2.toString(), String.class);
//assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
System.out.println(response.getStatusCode().toString()+(HttpStatus.OK).toString());
System.out.println(response.getBody()+"test");
return response.getBody();
}
Provider3 Controller
反正 他是複製 Provider 我們直接看源碼
這邊很簡單沒做什麼我們看 Consumer2
@GetMapping("/ep2")
public String home(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) {
String message = "Hello world" + port+ employeeId+employeeId2;
logger.info("[eureka-provide2][EurekaServiceProviderApplication][home], message={}", message);
return message;
}
這邊很簡單沒做什麼我們看 Consumer2
@GetMapping("/ep2")
public String home(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) {
String message = "Hello world" + port+ employeeId+employeeId2;
logger.info("[eureka-provide2][EurekaServiceProviderApplication][home], message={}", message);
return message;
}
Provider 3 配置文件
記得換為 eureka-provider2 ,以便讓我們的 Consumer2 可以調用到
name: eureka-provider2
name: eureka-provider2
Consumer2 Controller
注意看 Url這邊可以看到 我們沒有再讓往Zuul 去訪問我們的 consumer2 了 因為我們是讓 Provider 去直接 調用 我們的 consumer2 , 可以注意 url 的調用 address 裡面的 hello2
@RestController
public class ConsumerController {
private final Logger logger = LoggerFactory.getLogger(ConsumerController.class);
@Autowired
private HomeClient homeClient;
@GetMapping("/hello2/{id}/{id2}")
public String hello(@PathVariable(name="id") Integer employeeId,@PathVariable(name="id2") Integer employeeId2) {
System.out.print(employeeId2);
String message = homeClient.home(employeeId,employeeId2);
logger.info("[eureka-fegin2][ConsumerController][hello], message={}", message);
// log.info("[eureka-ribbon][EurekaRibbonConntroller][syaHello], message={}", message);
return message ;
}
}
@RestController
public class ConsumerController {
private final Logger logger = LoggerFactory.getLogger(ConsumerController.class);
@Autowired
private HomeClient homeClient;
@GetMapping("/hello2/{id}/{id2}")
public String hello(@PathVariable(name="id") Integer employeeId,@PathVariable(name="id2") Integer employeeId2) {
System.out.print(employeeId2);
String message = homeClient.home(employeeId,employeeId2);
logger.info("[eureka-fegin2][ConsumerController][hello], message={}", message);
// log.info("[eureka-ribbon][EurekaRibbonConntroller][syaHello], message={}", message);
return message ;
}
}
Consumer2 homeClient
可以注意我們的 這邊就是填 Provider3 註冊到 Eureka的名字 也就是 eureka-provider2
@FeignClient(value ="eureka-provider2",fallbackFactory=HystrixClientFallbackFactory.class)
public interface HomeClient {
@GetMapping("/ep2")
public String home(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) ;
}
好了都沒問題的話 就 啟動 吧!
@FeignClient(value ="eureka-provider2",fallbackFactory=HystrixClientFallbackFactory.class)
public interface HomeClient {
@GetMapping("/ep2")
public String home(@RequestParam (value="id", required = false) Integer employeeId,@RequestParam (value="id2", required = false) Integer employeeId2) ;
}
啟動
前面步驟就不說了
可以看到我訪問的是 helloEx
http://localhost:9000/feign-consumer/helloEX/1/12?token=Bearer%20eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1Nzc5MTUxNTksInVzZXJuYW1lIjoiamFjayJ9.UMUZWzh_ZTkhKxoSBfglSualToOTn9dm-WE9D3_huT4
這邊會覺得,有沒有更視覺化的東西可以看阿
別忘了我們的 Zipkin 就是在做這些事,我們打開
花了點時間 我把 zipkin 弄進去 docker-compose了,請注意 zipkin 啟動順序有差
version: '2'
services:
elasticsearch:
build:
context: elasticsearch/
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
logstash:
build:
context: logstash/
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5000:5000"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch
kibana:
build:
context: kibana/
volumes:
- ./kibana/config/:/usr/share/kibana/config:ro
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch
rabbitmq :
build:
context: rabbitmq /
volumes:
- ./rabbitmq/config/:/usr/share/rabbitmq/config:ro
ports:
- "5672:5672"
- "15672:15672"
networks:
- elk
depends_on:
- elasticsearch
zipkin:
build:
context: zipkin /
volumes:
- ./zipkin/config/:/usr/share/zipkin/config:ro
# Environment settings are defined here https://github.com/openzipkin/zipkin/tree/1.19.0/zipkin-server#environment-variables
environment:
- RABBIT_ADDRESSES=192.168.99.100:5672
- RABBIT_USER=guest
- RABBIT_PASSWORD=guest
- RABBIT_QUEUE=zipkin
- SELF_TRACING_ENABLED=false
#- RABBIT_VIRTUAL_HOST=/admin_host
- JAVA_OPTS=-Dlogging.level.zipkin
#=DEBUG -Dlogging.level.zipkin2=DEBUG
ports:
# Port used for the Zipkin UI and HTTP Api
- "9411:9411"
# Uncomment if you set SCRIBE_ENABLED=true
# - 9410:9410
networks:
- elk
depends_on:
- elasticsearch
networks:
elk:
driver: bridge
應該每次初次啟動 zipkin都會找不到 rabbitmq 而退出
docker start "zipkin name"

服務啟動
好了之後 我們的追蹤鏈也很清楚

http://localhost:9000/feign-consumer/helloEX/1/12?token=Bearer%20eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1Nzc5MTUxNTksInVzZXJuYW1lIjoiamFjayJ9.UMUZWzh_ZTkhKxoSBfglSualToOTn9dm-WE9D3_huT4
別忘了我們的 Zipkin 就是在做這些事,我們打開
花了點時間 我把 zipkin 弄進去 docker-compose了,請注意 zipkin 啟動順序有差
version: '2'
services:
elasticsearch:
build:
context: elasticsearch/
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
logstash:
build:
context: logstash/
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5000:5000"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch
kibana:
build:
context: kibana/
volumes:
- ./kibana/config/:/usr/share/kibana/config:ro
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch
rabbitmq :
build:
context: rabbitmq /
volumes:
- ./rabbitmq/config/:/usr/share/rabbitmq/config:ro
ports:
- "5672:5672"
- "15672:15672"
networks:
- elk
depends_on:
- elasticsearch
zipkin:
build:
context: zipkin /
volumes:
- ./zipkin/config/:/usr/share/zipkin/config:ro
# Environment settings are defined here https://github.com/openzipkin/zipkin/tree/1.19.0/zipkin-server#environment-variables
environment:
- RABBIT_ADDRESSES=192.168.99.100:5672
- RABBIT_USER=guest
- RABBIT_PASSWORD=guest
- RABBIT_QUEUE=zipkin
- SELF_TRACING_ENABLED=false
#- RABBIT_VIRTUAL_HOST=/admin_host
- JAVA_OPTS=-Dlogging.level.zipkin
#=DEBUG -Dlogging.level.zipkin2=DEBUG
ports:
# Port used for the Zipkin UI and HTTP Api
- "9411:9411"
# Uncomment if you set SCRIBE_ENABLED=true
# - 9410:9410
networks:
- elk
depends_on:
- elasticsearch
networks:
elk:
driver: bridge
docker start "zipkin name"

服務啟動



Saturday, August 17, 2019
websocket 達到百萬連接?(三) 端口 驗證
端口重複使用? 假象?
https://colobu.com/2019/02/23/1m-go-tcp-connection/
在看了下數據後 最下面貼文 發現了是不是只是 本地端 的假象?
在看了下數據後 最下面貼文 發現了是不是只是 本地端 的假象?
來實驗一下
在使用docker 虛擬連接發現docker 創建的連線數是正常的嗎
開了兩台 client 模擬客戶端 每台上限65536 ,可以看到 server 確實達到
接近12萬連線數 所以 這個就取決的server的硬件是否強大囉

後面 其中一docker 可能掛了還是怎樣,連線數掉到剩一台client
數據 大概 滿仔數據 記憶體大概是 快接近 6g cpu接近10%左右,頻寬 回傳 1.4m
在使用docker 虛擬連接發現docker 創建的連線數是正常的嗎
開了兩台 client 模擬客戶端 每台上限65536 ,可以看到 server 確實達到
接近12萬連線數 所以 這個就取決的server的硬件是否強大囉

後面 其中一docker 可能掛了還是怎樣,連線數掉到剩一台client
數據 大概 滿仔數據 記憶體大概是 快接近 6g cpu接近10%左右,頻寬 回傳 1.4m
接近 剛才的 部落格實測數據
Friday, April 5, 2019
Docker 環境安裝 Redis 到外網訪問
寫到一半的時候發現,那我們的東西 ,都放在裡面的話是不是不能拿出來???
當然要想辦法給外面用,所以我找到了大概這些東西
當然要想辦法給外面用,所以我找到了大概這些東西
- docker 簡單指令
- docker 訪問 外部文件(簡單版) 直接 跟著做
- docker 映射端口 至 外網 直接 跟著做
Docker 簡單指令
簡單翻了一下,大概搭建到完成Redis 使用的指令
- docker ps 類似 linux 管理 目前containers 那些被啟動
- docer stop start restart containers開開關關
- docker -d -p 外部端口 ip映射
- docker -v 掛載 外部文件會用到
- docker --name containers 名稱
- docker-machine ip default 查docker 實體ip
- docker exec -it {ps_name} bash 中括號不算
- docker rm 砍 containers用的 (我目前還沒用到)
看得很模糊走一次就知道了
Docker install Redis
在Redis 裡面呢 假設我們要配置服務器的話那麼
- docker search redis
- docker pull redis:latest
- docker images
執行完後會下載 Redis 最後一個版本囉,接下來看下面 就是大概就這邊比較可以學到東西
Docker Run Redis!
上面裝完了基本上就可以 來創造我們的一個 containers
這是 這次的主角 配置 參數 ,那麼我將會根據 步驟 來 反白我們參數目前進行的部分
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis13 redis redis-server /usr/local/etc/redis/redis.conf
Docker 查詢 docker 實體機 位置
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis13 redis redis-server /usr/local/etc/redis/redis.conf
- docker-machine ip default 查docker 實體ip
Docker 訪問外部 conf
https://hub.docker.com/_/redis/
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis13 redis redis-server /usr/local/etc/redis/redis.conf
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis13 redis redis-server /usr/local/etc/redis/redis.conf
在Redis 裡面呢 假設我們要配置服務器的話那麼怎麼辦呢,我想到可以用vim去配置,或修改文件,後來想想,那既然已經cmd能不能就是直接有本地端直接配置 conf文件呢,查找了一下
大致上是這樣的,我找到了一個最間單的方法,要比較完整的請找 -v 參數 或者是 volume??
在windows 裡面裝的 docker 要讀 conf的 系統大致上已經幫我們配置了一個地方可以放也就是
C:\Users
這個目錄
我們把 Redis 伺服器配置文件放到這個地方,這個文件可以從 我們編譯 Redis 的地方 目錄可以拿的到
所以從這裡把配置文件redis.conf複製到C:\Users\
那我們的Redis 基本上就可以抓到了
Docker 映射端口至外網
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis14 redis redis-server /usr/local/etc/redis/redis.conf
這串指令我還沒詳細介紹過 ,我大致從頭在講一次,docker 啟動 一個Redis 然後 會去映射端口 到 192.168.99.100:56379這個端口,被映射端口為6379 然後 我們的配置文件位於 C:\Users\裡面的redis.conf 在這邊寫法為 /c/Users/redis.conf ,然後映射到虛擬機的位置為/usr/local/etc/redis/redis.conf ,接下來我們創造的 container 他的名字叫做myredis14 然後 選擇啟動哪個 Image 也就是redis ,然後 呼叫系統服務
redis-server /usr/local/etc/redis/redis.conf 他的配置文件為 /usr/local/etc/redis/redis.conf
我們的目標要把Redis 端口映射到port :56379,首先 我們先看 docker ps
首先我們要先配置文件給設定正確的ip
docker inspect 137|grep -i add 搜尋 此 containers 裡面Ip位置 ,目前還不知道docker 架構所以我隨便說的,可能 docker 想像是一個vm 然後 你啟動她一定是抓取內網ip等等等等,服務配置文件就是去監聽自己的端口172.17.0.2 所以 虛擬機裡的服務去監聽自己
那們我們來更動一下位置 設為 bind 172.17.0.2
接下來,設定完畢後我們可以 來啟動了
這邊的話假設要看文件是否有更動呢,
docker run -d -p 192.168.99.100:56379:6379 -v /c/Users/redis.conf:/usr/local/etc/redis/redis.conf --name myredis14 redis redis-server /usr/local/etc/redis/redis.conf
首先我們的 docker ps 管理器 為空,那麼可以來下指令
沒意外可以看到我們的 容器為 myredis14 已經被啟動了!
弄個大概我們可以把它產生 一個 image
docker commit 137a23d757d8 redis/testimage:version1
假設其他你有要儲存的東東,下次就可以繼續使用囉!

















