23-06到11知识积累

序号
知识点
描述
  分析 频繁FGC问题

 堆内存使用过高: https://buzkgep88z.feishu.cn/docx/IW2YdwtOAoGKSDxbgoKcmsH5nvh

mat使用说明:JVM系列之:MAT工具使用教程 - 掘金 (juejin.cn)

使用教程:(43 封私信 / 80 条消息) 结合MAT分析OOM问题(视频版) - 知乎 (zhihu.com)

  线程分析实例 ‍⁢⁣⁡‍⁡⁡⁢‬‌⁡⁡⁢⁣‌⁣⁤‌‌⁤⁣⁤⁢⁤⁢⁡‬⁢⁢‍⁡⁢‌‌⁣⁢   https://buzkgep88z.feishu.cn/docx/DqhxdRgBnom3jOxKftfcR3Oin7c       开放平台Open-Msg启动优化 - 飞书云文档 (feishu.cn)
  一直最示最近关键字log ail -fn 100 application.log |grep 消费者线程
  dubbo 泛化调用 一次漫长的dubbo网关内存泄露排查经历 (qq.com)
  线程dump 分析

 https://fastthread.io/

想在关分析:https://duodian.feishu.cn/docx/YKBCduDxYofpK5xs2TSc2tWdnqh

  cookie写入

1、当请求进入 controller-action 写入 response resposne.addCookie(cookie01); – 如登录

2、写入cookie后,当再有请求 请求信息中会默认带 cookie 信息,到controller时request.getCookies可以

读取到写入浏览器的cookie。

如:

// 写入cookie

@RequestMapping("setCookie")
public String setCookie(){
Cookie cookie1=new Cookie("userName","liyanbo");
 cookie1.setMaxAge(30000);
 cookie1.setPath("/");
 cookie1.setSecure(false);
 httpServletResponse.addCookie(cookie1);
return "success";
}

// 请求获取cookie

@RequestMapping("getCookie")

public String getCookie(){
Cookie [] cookies= httpServletRequest.getCookies();
for (Cookie cookie : cookies) {
System.out.println("cookie.getName() = " + cookie.getName());
 System.out.println("cookie.getValue() = " + cookie.getValue());
 }
return "getCookie";
}
  logback.xml和logback-spring.xml

 

 
调用Dubbo接口:Thread pool is EXHAUSTED
 
一方案
<dubbo:protocol name="dubbo" port="20881" threadpool="fixed" threads="500" />
可以调整 threads参数
二方案
server:
port: 8085
dubbo:
application:
name: dubbo-provider
qos-enable: false
registry:
protocol:
name: dubbo
port: 20889
# 线程池大小为5
threads: 5
# 修改默认的消息派发机制 (all)
dispatcher: message
consumer:
check: false
provider:
filter: -validation
 

参考02:‍‌⁢‌⁢⁤⁤‬‬⁢⁤‬⁣⁢⁤‬‬⁢‬⁢⁤⁢‌‍⁢⁤⁢‍‬⁢⁡调用Dubbo接口:Thread pool is EXHAUSTED - 飞书云文档 (feishu.cn)

三方案

‍⁢‍⁢‬⁡⁡⁡⁤⁡⁡⁤⁢‍‬⁣‍⁤⁢⁢⁢⁣‌⁣‌‌⁣‬‌⁤‬‍⁡⁢⁣⁡DSF常见问题汇总 - 飞书云文档 (feishu.cn) 第6项有类型问题描述解决

 

一般dubbo 线程池数量设置200 正常,如果超过报Thread pool is Exhusted 应该考虑程序方法执行时间是否可以优化。

  dubbo -ds 接入详细说明

 testProject2.zip

 

手动调用dubbo接口

telnet 10.27.189.213 20880
进入后回车然后录入下面命令 或本地(telnet 127.0.0.1 20880)
invoke com.dmall.open.oauth.service.AuthDubboService.checkToken2({json串})
 
 
 

全文总结

 

1.对象使用{ }表示
2.List/Set使用[ ]表示
3.Map使用{ }表示
4.内部类使用$符号
5.枚举类使用name
6.在使用{ }的时候最好指定"class".

7月

 

 

 

序号
知识点
备注
  dubbo 实现接口

dubbo 分服务提供和服务消费

两者都需要实现 相应接口类,

可以将接口类单独做为一个moudle 来做接口,服务消费和服务生产者都实现接口类。

如果没有接口类 分别在服务提供和服务消费 实现包名相同的接口类也可以,如都实现接口 com.lyb.service.IorderService,

消费者也可以引用调到对应的 dubbo生产者实现的服务。

zkCli.cmd

查看zookeeper 注册服务 ls /dubbo/com.ivan.service.provider.UserService/providers

 

 

httpclinet 设置

 

 

可以设置 1000 ,

max_conn_per_route :200

max_conn_total:1000

http_request_timeout:8000

 

20台服务器,因为每个请求耗时较长,所以需要较多服务机器,原来 top90 到达20秒改造后降低到 8秒多。

RestTemplate方式

1
@Configuration
public class RestTemplateAutoConfiguration {
 
    @Autowired
    private RestTemplateBuilder builder;
    @Bean
    public RestTemplate restTemplate() {
 
        builder.setConnectTimeout(Duration.ofSeconds(3))
                .setReadTimeout(Duration.ofMillis(http_request_timeout))
                .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(
                        HttpClientBuilder.create()
                             // 修改前   .setMaxConnTotal(200)
                             // 修改前   .setMaxConnPerRoute(40)
                                    .setMaxConnTotal(max_conn_total)
                                .setMaxConnPerRoute(max_conn_per_route)
                                .disableAutomaticRetries()
                                .useSystemProperties().build())
 
                ).build();
    }
}

 

开放平台高峰每分钟 50000 请求平均 每秒1000

如果请求 等待在不算在响应超时 ,如请求较多 请求在等待 10秒+8秒真实请求,所以amp中会出现 设置http请求时间是8秒但amp

中显示 tp90 请求时长是20秒

 

maxConnTotal是同时间正在使用的最多的连接数
maxConnPerRoute是针对一个域名同时间正在使用的最多的连接数

 

 

 

httpClinet  使用方式

private static HttpClient client;
  static {
    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(5000)
            .setConnectionRequestTimeout(3000)
            .setSocketTimeout(5000).build();
    client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
            .build();
  }

 

9月

序号
问题
处理
1

dubbo 服务启动报错问题

java.lang.RuntimeException: [source error] getPropertyValue (Ljava/lang/Object;Ljava/lang/String;)

Ljava/lang/Object; in org.apache.dubbo.common.bytecode.Wrapper4: inconsistent stack height -1

Doubbo 服务启动异常:
原因是最新添加的dubbo服务接口中,有个接口方法类型是void却以getXXX开头,导致dubbo服务在产生该代理类的时候报错误

,具体原因是用Java反射调用该方法时,getXXX开头的方法却未获取到返回值;

 

 duoob的service的方法名最好不要用getOrders这种以get...开头,有可能启动报错:

2

dubbo 服务在消费端设置超时间不起作用

@Reference(check = false,timeout = 30000)
private SdkProducerDubboService sdkProducerDubboService;
设置后超时间还是1000ms 1秒超时 问题分析

原因:

1、因为在一个服务中多个地方 注入

@Reference(check = false)
private SdkProducerDubboService sdkProducerDubboService;
所以如果想要 设置timeout 生效需要在 注入该SdkProducerDubboService 的地方都加@Reference(check = false,timeout = 30000)就可以生效了
如果 消费方没有配置,提供方配置了,使用提供方配置; 如果消费方配置了,提供方也配置了使用消费方配置 (超时时间或重试次数等)
2、dubbo 的接口设置超时间,官方建议在 提供者位置加超时间
 
  • 作为服务的提供方,比服务消费方更清楚服务的性能参数,如调用的超时时间、合理的重试次数等
 
  Idea 开放平台dmall-open-all 其中有服务不能正常动问题
如果遇到

nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException:notation-specified bean name 'elasticSearchConfig'
  for bean class [com.dmall.open.app.config.ElasticSearchConfig] conflicts with existing,
non-compatible bean definition of same name and class [com.dmall.open.api.config.ElasticSearchConfig] An

需要清理以下 target 目录 然后重新打包编译 生成后才可以正常使用,去掉maven 配置
  use setting from .mvn/Maven.conifg(待确定是什么意思)
 Starting AuthorizationServerApplication on Bj-yanboli with
 PID 16672 (D:\dmall-repository\org\springframework\boot\spring-boot-starter-parent\2.1.7.RELEASE\target
 \classes started by Administrator in
  windows 按装多个jdk版本 不生效问题

建立多个 JAVA_HOME

如果先按装的 jdk 1.8 ,再按装1.7 , java -version 一直是1.8

可调整 :

把系统变量的Path中的%JAVA_HOME%\jre\bin 和 %JAVA_HOME%\bin 放在最前面
 

maven项目引入本地jar包

 

 

1、在项目录新建 lib将对应的jar 包放入

2、 file->project structure 加入jar包

3、pom文件加节点

<dependency>
    <groupId>com.dmall.open</groupId>
    <artifactId>open-sdk</artifactId>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/dmall-open-sdk-2.0.0-0717.jar</systemPath>
    <version>2.0.1-RELEASE</version>
</dependency>

ps:

${project.basedir} 系统变量 指项目根目录

gropuId和artfactId 在要引入的jar包里可以看到 mata-inf

 

11月

序号
标题
内容
  reids 结构 set/zset 使用场景 1、set 应用场景 如一个Key ,对应多个value, 如需要订阅多个topic ,topic放到缓存中就可以用 set结构,
增加: redisTemplate.opsForSet().add(topicsKey, topic);
获取:redisTemplate.opsForSet().members(kafkaTopicsKey)
ps: 1个Key对应不重复的多个value
2、zset针对一个key对应多个value ,有排序的增加访问次数

 

private Mono<Boolean> incrementCount(String key, String value,Integer expireDays) {
    return redisTemplate.opsForZSet().incrementScore(key, value, 1)
            .flatMap(count ->
                    redisTemplate.getExpire(key).defaultIfEmpty(Duration.ZERO).flatMap(duration -> {
                        if (duration.getSeconds() <= 0) {
                            return redisTemplate.expire(key, Duration.ofDays(expireDays != null ? expireDays : DEFAULT_DAYS));
                        }
                        return Mono.just(true);
                    })
            );
}
1 redission lock,分布式锁应用
// 主方法
public void mainMethod(){
  try{
          Pair<Boolean, RLock> lockPair = this.tryLock(taskId);
    if (!lockPair.getLeft()) {
          .....
        messageTaskLog.setSuccessStatus(SuccessStatusEnum.FAIL.getStatus());
         messageTaskLog.setFailMessage("推送任务未获取到锁");
        return;
        }
  
       RLock lock = lockPair.getRight();
    }
    catch(Exception ex){
  
    }
    finally{
    lock.unlock();
  }
}
 
获取锁方法
/**
 * 尝试获取锁最多等待2秒
 * 上锁后60秒自动释放锁防止死锁
 */
private Pair<Boolean, RLock> tryLock(Long taskId) {
    RLock lock = redissonClient.getLock(PushTaskConstant.getLockKey(taskId));
    try {
        return Pair.of(lock.tryLock(260, TimeUnit.SECONDS), lock);
    catch (InterruptedException e) {
        log.error("推送任务加锁异常, taskId:{}, e:", taskId, e);
        return Pair.of(false, lock);
    }
}
  flatMap

flatMap方法的主要用途是将一个流中的每个元素映射为一个流,并将这些流合并为一个流。

这个方法通常用于处理嵌套的集合或数组,以便将它们展开为单个流。

例如,假设您有一个包含多个列表的列表,您希望将它们合并为一个单独的列表。

您可以使用flatMap方法将每个列表映射为一个流,并将这些流合并为一个流,从而得到一个包含所有元素的单独列表。

List<List<Integer>> lists = Arrays.asList(
    Arrays.asList(1, 2, 3),
    Arrays.asList(4, 5, 6),
    Arrays.asList(7, 8, 9)
);

List<Integer> result = lists.stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList());

System.out.println(result); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
  @DependsOn 使用方式

GitHub Copilot: `@DependsOn`是Spring框架中的一个注解,用于指定Bean之间的依赖关系。

通过使用`@DependsOn`注解,您可以指定一个或多个Bean的名称,以确保这些Bean在当前Bean之前被初始化。

以下是一个示例代码,演示如何在Spring中使用`@DependsOn`注解:

```java
@Component
@DependsOn("dependencyBean")
public class MyBean {
// ...
}


kafka
https://blog.csdn.net/dong__CSDN/article/details/129857319

  flatMap 02

GitHub Copilot: `flatMap`方法是一种响应式编程中的操作符,它可以将一个`Mono`或`Flux`对象转换为另一个`Mono`或`Flux`对象,并且可以在转换过程中进行一些额外的操作。

在这段代码中,`flatMap`方法的作用是将`incrementScore`方法返回的`Mono`对象转换为另一个`Mono`对象,并在转换过程中进行一些额外的操作。具体来说,

它首先使用`getExpire`方法获取有序集合的过期时间,并使用`defaultIfEmpty`方法设置默认值为`Duration.ZERO`,以避免在没有设置过期时间的情况下出现`NullPointerException`异常。

然后,它使用`flatMap`方法来处理`getExpire`方法的返回值。在`flatMap`方法中,它检查有序集合的过期时间是否小于等于0秒。如果是,则使用`expire`方法设置有序集合的过期时间为默认值`DEFAULT_DAYS`天,并返回`Mono.just(true)`;

否则,返回`Mono.just(true)`。

需要注意的是,`flatMap`方法返回的是一个`Mono`对象,它表示一个异步计算结果。如果您需要等待异步计算完成并获取结果,可以使用`block()`方法或`subscribe()`方法。例如:

```java
Mono<Boolean> result = redisTemplate.opsForZSet().incrementScore(key, value, 1)
.flatMap(count ->
redisTemplate.getExpire(key).defaultIfEmpty(Duration.ZERO).flatMap(duration -> {
if (duration.getSeconds() <= 0) {
return redisTemplate.expire(key, Duration.ofDays(DEFAULT_DAYS));
}
return Mono.just(true);
})
);

result.block(); // 等待异步计算完成并获取结果
```

 

  multipartfile和base64传输文件区别

GitHub Copilot: Java后端接口传输文件时,可以选择使用Base64编码或MultipartFile类型。这两种方式各有优势,具体取决于您的需求和使用场景。

使用Base64编码传输文件的优势:

1. 可以将文件内容直接嵌入到JSON或XML等数据格式中,方便传输和处理。
2. 可以避免一些网络传输问题,例如文件名中包含特殊字符、文件大小超过限制等问题。
3. 可以避免一些安全问题,例如文件上传时的文件类型检查、文件大小限制等问题。

使用MultipartFile类型传输文件的优势:

1. 可以直接将文件内容作为二进制数据传输,避免了Base64编码和解码的开销。
2. 可以直接获取文件的元数据,例如文件名、文件类型、文件大小等信息。
3. 可以直接将文件保存到本地磁盘或其他存储介质中,方便后续处理和管理。

需要注意的是,使用Base64编码传输文件时,需要将文件内容进行Base64编码和解码,会增加一些额外的开销。而使用MultipartFile类型传输文件时,需要注意文件大小限制和安全问题,例如文件类型检查、文件大小限制等问题。

因此,您可以根据具体的需求和使用场景选择合适的方式来传输文件。

other解释

https://blog.csdn.net/tales522/article/details/125571284

posted @ 2024-02-18 15:38  xiaoBai1001  阅读(15)  评论(0编辑  收藏  举报