0517零散问题整理

1. Long vs long

Long可以是null,long不可以。
Long是个Object,long是个primitive

long is a primitive, which must have a value. Simple.
Long is an object, so:

  • it can be null (meaning whatever you like, but “unknown” is a common interpretation)
  • it can be passed to a method that accepts an Object, Number, Long or long parameter (the last one thanks to auto-unboxing)
  • it can be used an a generic parameter type, ie Listis OK, but Listis not OK
  • it can be serialized/deserialized via the java serialization mechanism

Always use the simplest thing that works, so if you need any of the features of Long, use Long otherwise use long. The overhead of a Long is surprisingly small, but it is there.

2. How to get active consumer in a group? 如何获取当前正在消费Kafka partition的consumer,以便重复利用已创建的consumer,或者以防同时有两个consumer去消费同一个partition?

You cannot have multiple consumers -within the same consumer group- consuming data from a single partition.0517零散问题整理_第1张图片

  1. AdminClient
    consumer doesn’t tied to topic, they tied to consumer groups.
    所以首先得拿到所有consumer groups, 然后根据topic去筛选出符合的consumer group。
AdminClient adminClient = AdminClient.create(props); 
// I tried and found the props shoud be the same props as your KafkaConfig class.

//Here you get all the consumer groups
List<String> groupIds = adminClient.listConsumerGroups().all().get().
                       stream().map(s -> s.groupId()).collect(Collectors.toList()); 

//Here you get all the descriptions for the groups
Map<String, ConsumerGroupDescription> groups = kafkaClient.
                                               describeConsumerGroups(groupIds).all().get();
for (final String groupId : groupIds) {
    ConsumerGroupDescription descr = groups.get(groupId);
    //find if any description is connected to the topic with topicName
    Optional<TopicPartition> tp = descr.members().stream().
                                  map(s -> s.assignment().topicPartitions()).
                                  flatMap(coll -> coll.stream()).
                                  filter(s -> s.topic().equals(topicName)).findAny();
            if (tp.isPresent()) {
                //you found the consumer, so collect the group id somewhere
            }
} 
                       

然后悲剧的是,我试了,然后当我同时运行一个程序,这个程序先create一个consumer,再用adminClient找,发现找不到这个consuemr。

  1. 所以最后我就放弃这种方法,直接在主文件定义了一个map>。但是这种情况下,不好关闭consumer。

  2. 所以我又采取了第三种方案,每个方法create和close consumer,然后synchronize这些子方法。

3. 给api endpoint加锁

https://www.baeldung.com/java-concurrent-locks
当时不想让两个线程同时创建同一个partition的kafka消费者,想给api endpoint加锁来着,后来发现我可以用synchronized的关键字去sync这些endpoint的函数。

4. 我发现,如果多个client在同时request一个endpoint/url:

  1. 当创建一个新的web request的时候,spring会为它创建一个新的线程, BUT:
    用debug模式,然后同时打开三个网页request同一个endpoint,会发现这个endpoint下的function是被依次执行三遍的。从不同的PC发出request应该也是这样。看似不同web request的线程之间是相互block的。
    但是,又说spring是线程不安全的,处理这些线程安全是开发者的任务。
    所以猜测,spring内部有一些它自己线程的机制… 不是说一定不安全,一定会并发,但是不保证一个web request线程运行时,一定会block其他web request线程吧… 总而言之,还是自己处理一些不同web request之间的synchronize问题吧?

  2. 在没有synchronized的情况下,如果用多线程call同一个接口,不一定要url一样,大概就是同一个address:port,就会报错:ConnectionClosedException
    但是不明白,为什么debug的情况下,当我们调用一个endpoint,这时候再开一个新的浏览器窗口,这个新的不会被运行,直到第一个调用被处理完

5. when spring create a new thread?

5.1 Is Spring controller/service/singleton thread-safe?

Every new HTTP request generates a new thread.

If the container creates a new bean instance just for that particular request, we can say this bean is thread-safe.

If two different threads execute a method of the singleton at the same time, you’re not guaranteed that both calls will be synchronized and run in the sequence.

正如3中所说,我运行的时候用着debug模式,然后当前request正在processing的时候,我call了另一个request,看似另一个request一直没有被执行,直到当前的执行完?而且debug console里的thread在重新call了一个request后并没有任何改变?。。。debug console里还是有不止一个在running的endpoints的,因为call一个request就会开启多个thread。
但是我还是不懂two different threads execute a method of the singleton at the same time这种情况怎么会发生?明明另一个request完全被block了啊。可能spring内部机制…不能保证总是这样吧…

In other words, it’s your responsibility to ensure your code runs safely in the multithreaded environment. Spring won’t do that for you.

As you know, some user’s requests may be concurrent. Because of that fact, session beans aren’t thread-safe.

What about the request scope bean? Spring creates a new instance of such component for each web request. Each request is bound to a separate thread. Therefore, each instance of the request bean gets its own instance of the prototype(不像singleton的thread-unsafe) bean. In that case, you can consider the prototype as thread-safe.
感觉这种是我的情况。不,不是,我就没创建prototype bean应该。

when you define a controller as the prototype, the Spring framework will create a new instance for each web request it serves.

The bean is stateless if execution of its methods doesn’t modify its instance fields.
Usually, your beans have some fields.

5.2 Does Spring create new thread per request in rest controllers?

这个例子是写了一个Thread.sleep,但是在运行时,发现第一个request还在sleep的时候,第二个request已经开始运行了, “To my surprise Spring doesn’t block incoming requests.” 这个和我debug时发现的就恰好相反,这些request之间没有互
相block,即使用了sleep,还是阻止不了其他request的开始执行。

原因好像可以参考tomcat thread pool,另外有人给出解释:

It’s blocking in the sense that it blocks one thread: the thread taken out of the pool of threads by the servlet container (Tomcat, Jetty, etc., not Spring) to handle your request. Fortunately, many threads are used concurrently to handle requests, otherwise the performance of any Java web application would be dramatic.
If you have, let’s say, 500 concurrent requests all taking 1 minute to complete, and the pool of threads has 300 threads, then 200 requests will be queued, waiting for one of the threads to become available

大概就是说,不同的web request是由不同的thread来handle的,你只sleep/block当前运行它的thread而已。可能thread pool同时有两个可用的thread,那么被queue的这些web requests中就有两个会同时开始被两个thread执行。

6. synchronized关键词

我为什么需要用synchronized? 我的代码是如下情境:
Each time, when make web request, will create a different consumer, what will happen if 5 endpoints are making request, but only 4 partitions? The 5th will failed, since each consumer will assign to only one partition in my code.
加上spring又不会替我们管理线程。

6.1 Locks In Synchronized Methods

When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method’s object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.

You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class’s static fields is controlled by a lock that’s distinct from the lock for any instance of the class.

6.2. synchronized关键词

其实我找了那些lock不lock的,我都是想找个方法让不同的method之间相互block,也就是这些methods不能同时被run。后来发现其实很简单,用synchronize这个keyword就可以实现。用法也很简单,用了多线程测试,也的确实现了方法间互相block。

public class Example {
	private int value = 0;
	public synchronized int getNextValue(){        
	  return value++;    
	}
}

With that, you have a guarantee that only one thread can execute the method at the same time. The used lock is the intrinsic lock of the instance. If the method is static, the used lock is the Classobject of Example. If you have two methods with the synchronized keyword, only one method of the two will be executed at the same time because the same lock is used for the two methods. 6中也提到了。

等同于:

public int getNextValue() {        
   synchronized (this) {            
     return value++;       
   }    
 }

if you don’t want to use the intrinsic lock of the current object but another object, you can use another object just as a lock:

 private final Object lock = new Object();     
 public int getNextValue() {      
   synchronized (lock) {           
     return value++;       
   }  
 }

The lock is internal to the object so no other code can use the lock.

7. 如何在一个class内多次初始化实例化一个bean?

看着有点麻烦,没有深究,直接把那个class改成不是bean的了。而且本来,之前提到过,bean最好是stateless的,会线程更安全啥的,在5中提到,而有fields的bean不是stateless的。
什么叫有fields的,就是有成员变量的:

@Component
public class customResponse{
	private String id;  // field
	private String status; // field
}

8. What is the difference between finally and no finally?

Things that happen within the finally block are guaranteed to occur no matter what happens in the try-catch-block. If an exception happens that is not encapsulated by Exception (e.g., extends Throwable, such as various Errors), then it still runs the finally block.

9. @RequestParam vs @QueryParam vs @PathVariable vs @PathParam

framework path segment http query parameter
Jersey (JAX-RS) @PathParam @QueryParam
Spring RESTFul @PathVariable @RequestParam
example http://xyz.ir/{segment} http://xyz.ir/?param{param}

我用的@QueryParam,路径其实是:

@Path(http://xyz.ir/param)

call的时候用:

http://xyz.ir/param?a=2&b=3

10. 为什么wait()和notify()需要搭配synchonized关键字使用

当一个线程在执行synchronized 的方法内部,调用了wait()后, 该线程会释放该对象的锁, 然后该线程会被添加到该对象的等待队列中(waiting queue), 只要该线程在等待队列中, 就会一直处于闲置状态, 不会被调度执行。

11. yml中一些配置关键词:

zipkin: track rest call to see if success or fail, usually used in distributed environment.

rest-proxy: let my project call other projects max.

12. 需要@Component on JUnit test class吗?

一个被@Bean标注的method,在被@Inject到 Junit的Integration test时,会有红色波浪线说找不到bean,但其实debug和运行都能找到。然后在JUnit这个test class上加上@Component,红波浪线就消失了。
但其实那些有component 标注的class(不是method),就算@Inject到没有@Component的test class,也不会画红波浪线的。所以这里不应该有问题。
反正感觉有没有红波浪线,有@Bean,@Component的都是能注入到JUnit没有@Component的test class的。

13. Gradle build的时候integration test是No-source

网上有的解答实在build.gradle sourceset里写明integration test,而且java里面有main test integrationTest三个文件夹,但其实我的情况,只要把test里class改成以IT结尾,那么就能被识别为Integration test。

14. embeddedKafka deleing log failed error.

处理kafka的时候,虽然核心代码(用到kafka broker,和kafka相关部分的代码)是依次进行的,但不知道为啥三个进程同时在获取删除embeddedkafka的文件。
而且,即使只run一个testcase,log里仍然会有三次kafkaconfig的记录(应该不影响),而且总会有can’t deleting log since other processes are using it这样的error。

所以和多线程啥的无关,这个错误据说是kafka内部在windows上的错,我尝试了:

  1. 只建立一个embeddedkafkabroker
  2. 只run一个JUnit简单test
    仍然会有这个错。

https://stackoverflow.com/questions/57622587/spring-kafka-test-with-embedded-kafka-failed-on-deleting-logs

https://issues.apache.org/jira/browse/KAFKA-8145

https://issues.apache.org/jira/browse/KAFKA-1194

https://stackoverflow.com/questions/12558231/recompile-with-xlintdeprecation-for-details

15. How do I compile with -Xlint:unchecked?

https://stackoverflow.com/questions/8215781/how-do-i-compile-with-xlintunchecked
按如下设置了xlint 感觉没有用啊…

For IntelliJ 13.1, go to File -> Settings -> Project Settings -> Compiler -> Java Compiler, and on the right-hand side, for Additional command line parameters enter “-Xlint:unchecked”.

16. 同样是@SpringBootTest,build的时候标注为Integration test和普通test的区别?

许多地方给我的感觉是有spring context的是integration test. 那么既然都有spring context,为什么我们在build gradle的时候,要选一些为Integration test呢?
好像是因为用到restTemplate这样,验证web request的,习惯标注为Integration test。

https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/

https://stackoverflow.com/questions/54658563/unit-test-or-integration-test-in-spring-boot

https://stackoverflow.com/questions/10752/what-is-the-difference-between-integration-and-unit-tests

17. thread nullpointerexception

一个神奇的发现,如果一个thread run里只有logger.info和Thread.sleep,那么thread.start()的时候,会报nullpointerexception,debug的时候这个thread明明不是null,但是start的时候好像以为thread是null。但是改成system.out.println()就不会了。。。。不知道这是为什么

18. kendo in react: 超方便的包,快速实现floating label input, 下拉窗口等

https://stackoverflow.com/questions/48273219/significance-of-spring-application-name-in-bootstrap-properties

19. useSelector几点需要注意的:

"Per the useSelector API docs, useSelector relies on reference equality, not shallow equality. "

When the selector does only depend on the state, simply ensure that it is declared outside of the component so that the same selector instance is used for each render:

记得点标题的超链接,讲的非常好,看完以后我就把不能re-redender的bug解决了。

20. JavaScript中{arg}的花括号是什么意思

This is an ES2015 (also called ES6) shorthand to create objects.
{ product } is equivalent to { product: product }.
Basically, you end up with an object with a property called “product” that has the value of the product variable.

21. useSelector没有re-render界面

在trigger的时候,state里的respData就已经更新了,导致success的时候发现state没有更新,因此没有render界面,原因不明,但尝试了以下解决方法:

  1. 发现dispatch里传给action的参数,名字和state里respData重名,都叫respData,但不是这个引起的
  2. 发现之前写tsx时,自动生成的那些js,d.ts,.map文件并没有随着我的tsx代码而更新,把这些都删了,我也不知道为什么会生成这些文件,删了以后以后也没有再生成了。
  3. 重构代码后,两个component同时用到useselector
  4. Components要以大写字母开头,不然会识别不了

21. tsx文件自动生成js,map,t.ds文件,而且还不随着tsx代码而更新?

其实我删了那些文件后,好像也没有回来了,搜到以下这些,仅供参考:

unwanted js file and js-map files are being generated from ts

This will be caused by some process invoking the tsc command with a different configuration to the one you gave in your question.

In your visual studio project settings have a look for typescript options and try disabling compile on save / similar

Also, it would be worth checking your project directory for any other tsconfig files, in case there is another configuration that is causing the incorrect behavior.

Of course you’ll need to manually remove the two files and see if they come back after making any changes

你可能感兴趣的:(0517零散问题整理)