Spring Cloud认知学习(二):Feign的使用、熔断器Hystrix
Feign
Feign用于声明式调用服务
在上面的服务调用中,我们始终还是没有摆脱restTemplate,我们调用别的服务始终要使用restTemplate来发起。想想我们以前是怎么开发的(三层架构,controller调用service,service调用dao),controller调用service,feign就是为这种面向接口化编程需求而产生的。为什么说他能面向接口化编程呢?我们下面来演示。
使用示例
代码参考:Feign简单使用实验
考虑到服务可能有多个消费者,所以我们把共有的代码写到spring-cloud-common-data
中,这样所有的消费者都可以通过继承这个依赖包来获取Feign修饰的接口。
1.导入依赖:
在spring-cloud-common-data
中导入依赖:
<dependencies>
<!--增加feign依赖 start-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<!--旧版本的-->
<!--<artifactId>spring-cloud-starter-feign</artifactId>-->
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--增加feign依赖 end-->
</dependencies>
2.新建Feign Interface
在spring-cloud-common-data
创建一个interface:
package com.progor.study.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
// 由于这种服务的服务消费者可能比较多,放到共有依赖中。
@FeignClient(value = "MESSAGESERIVE")
public interface MessageService {
// 这里使用RequestMapping将服务提供者的方法与本地Service方法建立映射
@RequestMapping(value = "/msg/list", method = RequestMethod.GET)
Map<String, String> list();
}
@FeignClient
用来配置信息,可以配置当前interface对应哪个服务。搭配@RequestMapping
的效果就是调用对应服务的对应API接口。上面代码的效果就是从eureka中获取名为MESSAGESERIVE的服务的服务示例,调用服务实例的/msg/list
路由方法。
3.创建服务消费者
3.1 在服务消费者spring-cloud-user-consumer-80
中创建一个MessageController2,注入MessageService:
package com.progor.study.Controller;
import com.progor.study.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
// 这个控制器用来处理使用fegin的情况
@RestController
public class MessageController2 {
// 注入MessageService
@Autowired
private MessageService messageService;
@GetMapping("/msg2/list")
public Map<String, String> list() {
return messageService.list();
}
}
3.2.在spring-cloud-user-consumer-80
启用Feign:
由于在spring-cloud-common-data
中导入了fegin依赖,所以这里不需要再导入了。
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "USERSERIVE", configuration = MyConfig.class)
@EnableFeignClients // 使用feign
public class UserConsumer80Application {
public static void main(String[] args) {
SpringApplication.run(UserConsumer80Application.class, args);
}
}
4.测试
4.1:启动spring-cloud-eureka-server-7001
,spring-cloud-message-service-8004
,spring-cloud-message-service-8005
4.2:访问http://localhost/msg2/list
,这个URL调用的是MessageController2的API,而MessageController2里面调用的是被Fegin封装的MessageService的方法。
如果能访问成功,那说明了是我们使用Feign成功了。
从上面可以看出,使用了Feign之后,我们可以像以前一样调用Service来调用业务逻辑了。
补充:
- Feign默认是有负载均衡的,看一下
spring-cloud-starter-openfeign
依赖包,你会发现它有导入依赖spring-cloud-starter-netflix-ribbon
- 更多内容包括其工作原理,将会单章讲解,咕咕咕。
上一篇介绍一个用于声明式调用服务的组件Fegin,主要用于解决前面的服务调用与restTemplate耦合紧密的问题。 Spring Cloud认知学习(三):声明式调用Feign的使用
这一篇介绍一个新的组件Hystrix,Hystrix是一个熔断器,可以用于解决微服务调用中发送的服务熔断和服务降级问题。
Hystrix
* Hystrix是服务熔断器,用于解决服务熔断和服务降级的情况。
服务熔断和服务降级
- 主要是解决服务熔断和服务降级的问题。
服务熔断主要用了解决服务雪崩,我们先来介绍一下服务雪崩的概念。 - 服务雪崩:假如有很多个服务都需要调用A服务,但A突然卡住了,响应很慢,在高并发的情况下,此时A服务就会持有了过量的资源,而导致其他服务的资源不足,从而影响其他服务的使用,甚至可能传播性地导致整个系统崩溃。
- 服务熔断:熔断的概念是什么呢?就是假如说你家里用了超大的功率的电器,你家的电闸就会为了避免造成危险而帮你跳闸断电。对于服务雪崩也是这样的,他会防止服务占用过量的资源。
原理:用户的请求将不再直接调用服务,而是通过一个线程池来调用服务,当线程池中没有空闲的线程时,就会返回一个简单的执行结果(需要设定,可能是一个提示信息或者一个假数据)。 - 服务降级:当某一个主要的服务端的资源不够的时候,可能此时其他的不太重要服务需要进行关闭来为他腾出空间(就好像与支付功能相比,换头像这个功能就可以暂时为支付功能献身了),这就是服务的降级。虽然降级了,但理论上还应该给消费者一个保底的回应,比如说返回提示说服务已经关闭。由于此时服务的提供者已经关闭了,所以这个判断只能发生在服务的消费者中。
:对于上面的这两种情况,如果是服务熔断,既可以部署在消费者也可以部署在生产者,因为只是一个“等太久就不等待”的处理,这个等太久既可以事消费者判断也可以事生产者判断;如果是服务降级,由于此时服务提供者大多都关闭了,所以这时候Hystrix只能部署在消费者端。
:由于Hystrix其实就是对于错误情况的处理,服务的过度消耗资源(雪崩)和降级其实都是服务不可用,他们的处理在Hystrix其实都是一样的。所以下面就根据Hystrix的部署位置来演示。
简单使用示例:
下面的代码可以参考:Hystrix简单使用实验
部署在服务提供者
这次我们修改模块spring-cloud-user-service-8003
1.导入依赖:
<!--增加hystrix依赖 start-->
<!--旧版本的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--增加hystrix依赖 end-->
2.修改UserController,给listUser增加一个Hystrix处理方法listUserByHystirx。@HystrixCommand(fallbackMethod = "listUserByHystirx")
代表发生不可用的时候,就会调用listUserByHystirx来返回结果。
package com.progor.study.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.progor.study.entity.User;
import com.progor.study.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 java.util.ArrayList;
import java.util.List;
// 由于返回json数据,懒得加注解@ResponseBody了,加个RestController
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public User getUser(@PathVariable Integer id) {
User user = userService.getUser(id);
if (user == null) {
throw new RuntimeException("该ID:" + id + "没有对应的用户信息");
}
return user;
}
private static int count = 0;
@GetMapping("/user/list")
// fallbackMethod时发生错误时调用的方法,
// commandProperties用于配置熔断器,requestVolumeThreshold代表请求多少次就不再尝试调用原方法,直接调用错误处理方法。
@HystrixCommand(fallbackMethod = "listUserByHystirx",commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), //请求次数
}) //
public List<User> listUser() throws InterruptedException {
count = count+1; // 假装偶尔发生了bug
System.out.println(count);
// 偶尔发生时
// if (count%2 == 0){
// Thread.sleep(5000);
// }
// 一直发生时:
Thread.sleep(5000);
List<User> users = userService.listUser();
return users;
}
public List<User> listUserByHystirx() {
User user = new User(0,"null","null");
List<User> users = new ArrayList<>();
users.add(user);
return users;
}
}
<br>
3.在主程序类中开启hystrix:
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix // 开启hystrix
public class UserService8003Application {
public static void main(String[] args) {
SpringApplication.run(UserService8003Application.class, args);
}
}
4.启动spring-cloud-user-service-8003
,访问http://localhost:8003/user/list
,发现如果发生错误的时候,会调用listUserByHystirx来返回。
如果你通过服务消费者来调用8003的服务的话,这时候也会一样会在发生错误的时候,调用listUserByHystirx来返回。
注意,我上面的代码是一次执行成功,一次执行失败这样的顺序。
部署在服务消费者
目前我们只有一个服务消费者,所以我们要修改spring-cloud-user-consumer-80
1.在spring-cloud-user-consumer-80
模块导入依赖:
<!--增加hystrix依赖 start-->
<!--旧版本的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--增加hystrix依赖 end-->
2.修改MessageController2,增加@HystrixCommand
// 这个控制器用来处理使用fegin的情况
@RestController
public class MessageController2 {
@Autowired
private MessageService messageService;
@GetMapping("/msg2/list")
// 使用HystrixCommand
@HystrixCommand(fallbackMethod = "listByHystirx",commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), //请求次数
}) //如果请求次数达到5次都是失败,那么直接调用listByHystirx
public Map<String, String> list() {
return messageService.list();
}
public Map<String, String> listByHystirx() {
Map<String, String> map = new HashMap<>();
map.put("msg","服务端已停止服务");
return map;
}
}
3.修改主程序类,开始Hystrix,@EnableHystrix
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "USERSERIVE", configuration = MyConfig.class)
@EnableFeignClients // 使用feign
@EnableHystrix
public class UserConsumer80Application {
public static void main(String[] args) {
SpringApplication.run(UserConsumer80Application.class, args);
}
}
4.测试
- 启动
spring-cloud-user-consumer-80
和spring-cloud-eureka-server-7001
- 访问一次
http://localhost/msg2/list
。此时由于没有服务实例,那么应该会调用listByHystirx来返回结果。- 请注意我们之前创建的MessageService在8004和8005,如果我们没有启动8004或8005,那么此时eureka内部应该没有MessageService服务实例,所以你会发现会调用我们的错误处理方法中的结果来返回给我们,而如果我们调用
http://localhost/msg/list
由于我们没有做hystrix处理,那么就会报错;
- 请注意我们之前创建的MessageService在8004和8005,如果我们没有启动8004或8005,那么此时eureka内部应该没有MessageService服务实例,所以你会发现会调用我们的错误处理方法中的结果来返回给我们,而如果我们调用
- 启动
spring-cloud-message-service-8004
,访问http://localhost/msg2/list
,是访问成功的。【但由于我们设置了重试次数为5,如果你启动了8004还是访问失败,那么尝试重启一下80吧,不然要等重新拉取eureka的信息(30s大概)。】 - 再停掉
spring-cloud-message-service-8004
,访问http://localhost/msg2/list
,会调用listByHystirx来返回结果。
整合feign
Hystrix还可以与Fegin整合,也是相当于部署在服务消费者。
下面的代码可以参考:Hystrix整合Feign使用实验
1.修改Feign代码
由于我们只在spring-cloud-common-data
模块整合了fegin,所以我们要在spring-cloud-common-data
做实验了。
1.在spring-cloud-common-data
模块导入依赖。
<!--增加hystrix依赖 start-->
<!--旧版本的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--增加hystrix依赖 end-->
2.修改MessageService
,在FeignClient注解中增加fallback
// 由于这种服务的服务消费者可能比较多,放到共有依赖中。
// 使用fallback指定一个类,这个类实现了MessageService,发生服务不可用的时候就会调用这个类中方法
@FeignClient(value = "MESSAGESERIVE",fallback = MessageServiceHystrix.class)
public interface MessageService {
// 这里使用RequestMapping将服务提供者的方法与本地Service方法建立映射
@RequestMapping(value = "/msg/list", method = RequestMethod.GET)
Map<String, String> list();
}
3.创建MessageServiceHystrix:
package com.progor.study.service;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
// 注意,要使用@Component
@Component
public class MessageServiceHystrix implements MessageService {
@Override
public Map<String, String> list() {
Map<String, String> map = new HashMap<>();
map.put("msg","服务端已停止服务");
return map;
}
}
2.修改消费者
1.由于我们上面在MessageController2中使用了Hystrix,我们新建一个MessageController3:
@RestController
public class MessageController3 {
@Autowired
private MessageService messageService;
@GetMapping("/msg3/list")
public Map<String, String> list() {
return messageService.list();
}
}
2.修改spring-cloud-user-consumer-80
中的application.yml增加如下内容:
feign:
hystrix:
enabled: true # 用来开启fegin中的hystrix
注意,此时主程序类中的@EnableHystrix可以没有
3.测试:
启动spring-cloud-user-consumer-80
和spring-cloud-eureka-server-7001
,访问http://localhost/msg2/list
- 访问一次
http://localhost/msg3/list
。此时由于没有服务实例,那么应该会调用listByHystirx来返回结果。- 请注意我们之前创建的MessageService在8004和8005,如果我们没有启动8004或8005,那么此时eureka内部应该没有MessageService服务实例,所以你会发现会调用我们的错误处理方法中的结果来返回给我们,而如果我们调用
http://localhost/msg/list
由于我们没有做hystrix处理,那么就会报错;
- 请注意我们之前创建的MessageService在8004和8005,如果我们没有启动8004或8005,那么此时eureka内部应该没有MessageService服务实例,所以你会发现会调用我们的错误处理方法中的结果来返回给我们,而如果我们调用
- 启动
spring-cloud-message-service-8004
,访问http://localhost/msg2/list
,是访问成功的。【如果你启动了8004还是访问失败,那么尝试重启一下80吧,不然要等重新拉取eureka的信息(30s大概)。】 - 再停掉
spring-cloud-message-service-8004
,访问http://localhost/msg2/list
,会调用listByHystirx来返回结果。
Hystrix Dashboard
Hystrix Dashboard是一个监控Hystrix熔断器状况的组件,有图形化的数据统计界面,你可以通过查看熔断器的统计数据来判断服务的状况。
对于restTemplate和fegin整合Hystrix Dashboard的方式都是一样的。
下面来演示整合,代码可以参考:Hystrix Dashboard整合使用实验,PS,这里的commit的注释上一个版本提交错了一个代码,请以这个版本的为准
有点小问题,我以为我提交了一个错误的版本,没想到我revert成功了,参考这个版本的代码即可。上一个版本Hystrix整合Feign使用实验
不存在错误。
1.配置启动Hystrix Dashboard
0.创建模块spring-cloud-hystrix-dashboard-9001
1.导入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
2.主程序类添加注解@EnableHystrixDashboard:
@SpringBootApplication
@EnableHystrixDashboard
public class SpringCloudHystrixDashboard9001Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloudHystrixDashboard9001Application.class, args);
}
}
3.访问http://localhost:9001/hystrix
,如果能正常看到页面,那么就启动成功了。
上面启动了Hystrix Dashboard服务,但Hystrix Dashboard是一个接收服务的数据的组件,服务不开放数据,它也接收不了,下面会进行配置。
2.修改服务提供者
1.在服务提供者spring-cloud-user-service-8003中增加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.在spring-cloud-user-service-8003的主程序类中增加ServletRegistrationBean的Bean:【这个是在Finchley的时候增加的好像,以前可以不配这个Bean】
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix // 开启hystrix
public class UserService8003Application {
public static void main(String[] args) {
SpringApplication.run(UserService8003Application.class, args);
}
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.addUrlMappings("/hystrix.stream");//路径
return registrationBean;
}
}
3.修改8003的熔断器处理代码:
因为Hystrix dashboard只能检测发生被熔断器处理的方法。没有熔断处理的方法无法被监控。这里解开注释,用于测试时好时坏时,对于Hystrix dashboard的成图效果。
3.测试:
启动spring-cloud-user-service-8003
,spring-cloud-eureka-server-7001
在谷歌浏览器中查看localhost:8003/hystrix.stream
【如果是在火狐,可能会进行下载。】,这是8003开放的请求流,Hystrix dashboard实际上就是对这个流来分析的。
当你访问http://localhost:8003/user/list
的时候因为我们的代码问题,它偶尔会发生问题,此时上图的ping才会显示出不同的内容。
访问http://localhost:9001/hystrix
,是一个如下的页面:
在中间输入http://localhost:8003/hystrix.stream
,让Hystrix Dashboard监控这个流,然后点击下面的按钮,你就进入一个这样的图:
Delay是监控的刷新时间。
7色:中间的7种颜色的,要参考右上角的颜色问题。
- Success:代表请求成功
- Short-Circuited:代表熔断数
- Bad Request:代表抛出HystrixBadRequestException的次数
- Timeout:代表请求超时的次数
- Rejected:线程池拒绝数
- Failure:抛出异常的请求
- Error:最近10秒的错误比例
1圈:这个圈会随着七种数字的总和而变大,圈越大,访问越多;圈的颜色是其中颜色的混搭,比如成功为主的时候,偏于绿色,如果是偏于红色,那么说明请求失败很多。【绿、黄、橙、红】
1线:线是请求次数的高低,没有请求的时候就是一条直线,有请求的时候就是一张折线图。
想了解图中更多的内容可以参考:图内数据官方参考文档
Spring Cloud认知学习(二):Feign的使用、熔断器Hystrix的更多相关文章
- spring boot 2.0.3+spring cloud (Finchley)4、熔断器Hystrix
在分布式系统中服务与服务之间的依赖错综复杂,一种不可避免的情况就是某些服务会出现故障,导致依赖于他们的其他服务出现远程调度的线程阻塞.某个服务的单个点的请求故障会导致用户的请求处于阻塞状态,最终的结果 ...
- (转)Spring Cloud(二)
(二期)23.微服务框架spring cloud(二) [课程23]熔断器-Hystrix.xmind0.1MB [课程23]微服务...zuul.xmind0.2MB 熔断器-Hystrix 雪崩效 ...
- Spring Cloud 入门 之 Feign 篇(三)
原文地址:Spring Cloud 入门 之 Feign 篇(三) 博客地址:http://www.extlight.com 一.前言 在上一篇文章<Spring Cloud 入门 之 Ribb ...
- Spring Cloud(二):Eureka 服务注册中心
前言 服务治理 随着业务的发展,微服务应用也随之增加,这些服务的管理和治理会越来越难,并且集群规模.服务位置.服务命名都会发生变化,手动维护的方式极易发生错误或是命名冲突等问题.而服务治理正是为了解决 ...
- spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关)
spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关) zuul: routes: #路由配置表示 myroute1: #路由名一 path: ...
- Spring Cloud(Dalston.SR5)--Feign 声明式REST客户端
Spring Cloud 对 Feign 进行了封装,集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,Spring Cloud 实现的 Feign 客户端类名为 LoadBala ...
- Spring Cloud(二):服务注册与发现 Eureka【Finchley 版】
Spring Cloud(二):服务注册与发现 Eureka[Finchley 版] 发表于 2018-04-15 | 更新于 2018-05-07 | 上一篇主要介绍了相关理论,这一篇开始我们 ...
- 0.9.0.RELEASE版本的spring cloud alibaba sentinel+feign降级处理实例
既然用到了feign,那么主要是针对服务消费方的降级处理.我们基于0.9.0.RELEASE版本的spring cloud alibaba nacos+feign实例添油加醋,把sentinel功能加 ...
- spring cloud 专题二(spring cloud 入门搭建 之 微服务搭建和注册)
一.前言 本文为spring cloud 微服务框架专题的第二篇,主要讲解如何快速搭建微服务以及如何注册. 本文理论不多,主要是傻瓜式的环境搭建,适合新手快速入门. 为了更好的懂得原理,大家可以下载& ...
- Spring Cloud中关于Feign的常见问题总结
一.FeignClient接口,不能使用@GettingMapping 之类的组合注解 代码示例: @FeignClient("microservice-provider-user" ...
随机推荐
- optical simulation of quantum logic
量子逻辑的光学模拟(PRA, 1998) 主机中<1998Cerf.pdf> 核心: 1. 用一个光子的多条路径的叠加态来表示n qubits, 那么实验上干涉仪所包含的路径数为 2^n ...
- Selenium IDE使用指南一(爬虫脚本录制器)
安装 从Chrome或Firefox网络商店安装Selenium IDE . 启动IDE 安装后,通过从浏览器菜单栏中单击其图标来启动它. 故障排除 在菜单栏中没有看到Selenium IDE的图标? ...
- [不得不知道系列]Java面试你不得不知道的基础知识一
当今世界上使用最广泛的编程语言之一是Java.Java是通用的高级编程语言.核心java是java编程技术概念的基础,该术语由sun Microsystems用来描述Java的标准版本(JSE).核心 ...
- 看不懂来打我,Vue3的watch是如何实现监听的?
前言 watch这个API大家都很熟悉,今天这篇文章欧阳来带你搞清楚Vue3的watch是如何实现对响应式数据进行监听的.注:本文使用的Vue版本为3.5.13. 关注公众号:[前端欧阳],给自己一个 ...
- 新型大语言模型的预训练与后训练范式,苹果的AFM基础语言模型
前言:大型语言模型(LLMs)的发展历程可以说是非常长,从早期的GPT模型一路走到了今天这些复杂的.公开权重的大型语言模型.最初,LLM的训练过程只关注预训练,但后来逐步扩展到了包括预训练和后训练在内 ...
- 使用conditional 实现线程精准通讯
实现3个线程之间依次执行 比如有3个线程A,B,C ,需要按照顺序执行,ABC,ABC 依次执行. 这个使用可以使用 Lock 的 conditional来实现线程之间精准通讯. 点击查看代码 pac ...
- 移动端NES网页模拟器(3)
前言 前面2个章节已经封装好了摇杆和NES虚拟按键,现在配合jsnes这个包来完成一个移动端版的NES模拟器. 这是插件的github地址:bfirsh/jsnes 这个包可以直接拿来用,但是没有适配 ...
- 2024 盘古石数据取证 服务器部分wp
1. 分析内部IM服务器检材,在搭建的内部即时通讯平台中,客户端与服务器的通讯端口是:[答案格式:8888][★☆☆☆☆] 8065 2. 分析内部IM服务器检材,该内部IM平台使用的数据库版本是: ...
- DA14531芯片固件逆向系列(2)- 操作系统底层机制分析
首发于先知论坛 https://xz.aliyun.com/t/9186 概述 DA145x软件平台利用了由Riviera Waves许可的小型高效实时内核,内核提供以下功能: 任务创建和状态转换. ...
- 【Amadeus原创】本地安装gitlab,初始化管理员密码
注册还是无法登录,最后发现,需要初始化root密码. docker exec进去,然后执行gitLab-rails,修改密码, 然后登录即可. [root@ecs-9684 ~]# docker ex ...