<commit_before># Eagle

# 概要
Eagle是一个分布式的RPC框架，支持灵活的配置，支持分布式追踪，支持[Kryo][kryo]、[Hessian][hessian]等序列化协议，默认序列化使用kryo。提供Spring和SpringBoot插件，方便与Spring和SpringBoot集成。

# 特点
- 借助[Zookeeper][zookeeper]实现服务注册和发现。
- 分布式ID追踪，方便排查问题。
- 基于AQS实现高性能连接池。
- 提供failover和failfast两种高可用策略。
- 支持同步和异步回调两种机制。
- 提供接口方法请求时间、tps等监控信息。
- 提供和自定义服务端过载保护策略。

# jmh基准测试结果
> 运行基准测试步骤：
>  * cd eagle-benchmark
>  * mvn clean install
>  * cd eagle-benchmark-server/target
>  * tar -zxvf eagle-benchmark-server-1.4-assembly.tar.gz
>  * cd eagle-benchmark-server-1.4
>  * bin/start.sh
>  * cd eagle-benchmark/eagle-benchmark-client
>  * 在linux上运行 sh benchmark.sh，在window上运行 benchmark.cmd
>  * 注（修改benchmark.sh 中的 -t 参数修改线程数）
   
> macOs上的结果（16g内存，2.5 GHz Intel Core i7），启动16个线程。
   
   ![Image text](https://raw.githubusercontent.com/fang-yan-peng/eagle/master/benchmark_mac.jpeg)

> linux上的结果（64g内存，24核），启动80个线程。
   
   ![Image text](https://raw.githubusercontent.com/fang-yan-peng/eagle/master/benchmark_linux.jpeg)


# 例子
> 内置zookeeper，仅测试使用。生产环境请更换真实zookeeper地址，使用内置zookeeper有可能会报连接警告或者异常，更换真实zk地址即可。运行要求:
>  * JDK 1.7 or above
>  * 编译工具 [Maven][maven] or [Gradle][gradle]

## 添加依赖
   如果是spring,添加如下:
   ```xml
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-core</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-registry-zookeeper</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-transport-netty</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-spring-support</artifactId>
        <version>1.4</version>
    </dependency>
   ```
   如果是springBoot,添加如下:
  ```xml
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-core</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-registry-zookeeper</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-transport-netty</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
     <groupId>org.jfaster.eagle</groupId>
     <artifactId>spring-boot-starter-eagle</artifactId>
     <version>1.4</version>
   </dependency>
  ```
## 分布式调用追踪
```xml
在应用中一个接口通常会涉及到一系列服务的rpc调用，由于服务分布式部署导致出现问题排查相对困难。eagle框架在一次调用中生成的traceId是相同的，只要通过ELK等日志搜集系统把日志集中处理，那么输入traceId就可以获取整个链路的调用过程。
          C
         /    
例如 A - B   A调用B，B又调用C和D，那么在一次调用中，可以通过traceId，把整个调用串联起来。traceId是根据ip+进程号+时间戳+计数，生成的全局唯一id，如果框架内部获取的ip不准确可以通过，如-Dhost=10.110.69.17指定。
         \
          D
在业务代码中，当打印日志的时候，可以通过TraceContex.getOpaque()方法获取当前调用链中的traceId。打印出traceId，logger.info(TraceContex.getOpaque() + "xxxxxx")。这样就可以根据日志追踪整个调用过程。
更简单的方式是使用eagle框架提供的日志组件，配置如下：
```
### logback的配置
- 如果当前上下文中存在traceId，logback将在输出traceId，如果不存在traceId则输出N/A。用%traceId来展示traceId。
```xml
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="eagle.jfaster.org.trace.logback.TraceIdPatternLogbackLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%traceId] [%thread] %-5level %logger{36} -%msg%n</Pattern>
        </layout>
    </encoder>
</appender>
```
### log4j的配置
- 配置layout
```xml
log4j.appender.CONSOLE.layout=eagle.jfaster.org.trace.log4j.TraceIdPatternLayout
```
- 在layout.ConversionPattern中设置 %T来展示traceId
```xml
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%T] %-5p %c{1}:%L - %m%n
```

### 分布式追踪在程序中的应用

- 在spring配置文件中，添加<eagle:trace/> 配置，springboot不用添加额外配置。然后在需要追踪的类或者方法上打上@Trace注解

`src/main/java/eagle/jfaster/org/controller/TraceController.java`

```java
    package eagle.jfaster.org.controller;
    
    import eagle.jfaster.org.config.annotation.Refer;
    import eagle.jfaster.org.service.Calculate;
    import eagle.jfaster.org.service.Hello;
    import eagle.jfaster.org.trace.annotation.Trace;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.RequestMapping;<commit_msg>增加注解追踪和修改refer注入的bug<commit_after># Eagle

# 概要
Eagle是一个分布式的RPC框架，支持灵活的配置，支持分布式追踪，支持[Kryo][kryo]、[Hessian][hessian]等序列化协议，默认序列化使用kryo。提供Spring和SpringBoot插件，方便与Spring和SpringBoot集成。

# 特点
- 借助[Zookeeper][zookeeper]实现服务注册和发现。
- 分布式ID追踪，方便排查问题。
- 基于AQS实现高性能连接池。
- 提供failover和failfast两种高可用策略。
- 支持同步和异步回调两种机制。
- 提供接口方法请求时间、tps等监控信息。
- 提供和自定义服务端过载保护策略。

# jmh基准测试结果
> 运行基准测试步骤：
>  * cd eagle-benchmark
>  * mvn clean install
>  * cd eagle-benchmark-server/target
>  * tar -zxvf eagle-benchmark-server-1.4-assembly.tar.gz
>  * cd eagle-benchmark-server-1.4
>  * bin/start.sh
>  * cd eagle-benchmark/eagle-benchmark-client
>  * 在linux上运行 sh benchmark.sh，在window上运行 benchmark.cmd
>  * 注（修改benchmark.sh 中的 -t 参数修改线程数）
   
> macOs上的结果（16g内存，2.5 GHz Intel Core i7），启动16个线程。
   
   ![Image text](https://raw.githubusercontent.com/fang-yan-peng/eagle/master/benchmark_mac.jpeg)

> linux上的结果（64g内存，24核），启动80个线程。
   
   ![Image text](https://raw.githubusercontent.com/fang-yan-peng/eagle/master/benchmark_linux.jpeg)


# 例子
> 内置zookeeper，仅测试使用。生产环境请更换真实zookeeper地址，使用内置zookeeper有可能会报连接警告或者异常，更换真实zk地址即可。运行要求:
>  * JDK 1.7 or above
>  * 编译工具 [Maven][maven] or [Gradle][gradle]

## 添加依赖
   如果是spring,添加如下:
   ```xml
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-core</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-registry-zookeeper</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-transport-netty</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.jfaster.eagle</groupId>
        <artifactId>eagle-spring-support</artifactId>
        <version>1.4</version>
    </dependency>
   ```
   如果是springBoot,添加如下:
  ```xml
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-core</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-registry-zookeeper</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
       <groupId>org.jfaster.eagle</groupId>
       <artifactId>eagle-transport-netty</artifactId>
       <version>1.4</version>
   </dependency>
   <dependency>
     <groupId>org.jfaster.eagle</groupId>
     <artifactId>spring-boot-starter-eagle</artifactId>
     <version>1.4</version>
   </dependency>
  ```
## 分布式调用追踪
```xml
在应用中一个接口通常会涉及到一系列服务的rpc调用，由于服务分布式部署导致出现问题排查相对困难。eagle框架在一次调用中生成的traceId是相同的，只要通过ELK等日志搜集系统把日志集中处理，那么输入traceId就可以获取整个链路的调用过程。
          C
         /    
例如 A - B   A调用B，B又调用C和D，那么在一次调用中，可以通过traceId，把整个调用串联起来。traceId是根据ip+进程号+时间戳+计数，生成的全局唯一id，如果框架内部获取的ip不准确可以通过，如-Dhost=10.110.69.17指定。
         \
          D
在业务代码中，当打印日志的时候，可以通过TraceContex.getOpaque()方法获取当前调用链中的traceId。打印出traceId，logger.info(TraceContex.getOpaque() + "xxxxxx")。这样就可以根据日志追踪整个调用过程。
更简单的方式是使用eagle框架提供的日志组件，配置如下：
```
### logback的配置
- 如果当前上下文中存在traceId，logback将在输出traceId，如果不存在traceId则输出N/A。用%traceId来展示traceId。
```xml
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="eagle.jfaster.org.trace.logback.TraceIdPatternLogbackLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%traceId] [%thread] %-5level %logger{36} -%msg%n</Pattern>
        </layout>
    </encoder>
</appender>
```
### log4j的配置
- 配置layout
```xml
log4j.appender.CONSOLE.layout=eagle.jfaster.org.trace.log4j.TraceIdPatternLayout
```
- 在layout.ConversionPattern中设置 %T来展示traceId
```xml
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%T] %-5p %c{1}:%L - %m%n
```

### 分布式追踪在程序中的应用

- 在spring配置文件中，添加```xml<eagle:trace/>``` 配置，springboot不用添加额外配置。然后在需要追踪的类或者方法上打上@Trace注解。

`src/main/java/eagle/jfaster/org/controller/TraceController.java`

```java
    package eagle.jfaster.org.controller;
    
    import eagle.jfaster.org.config.annotation.Refer;
    import eagle.jfaster.org.service.Calculate;
    import eagle.jfaster.org.service.Hello;
    import eagle.jfaster.org.trace.annotation.Trace;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.RequestMapping;
{'fraction_non_alphanumeric': 0.14537240820108885, 'fraction_numerical': 0.012741804702884281, 'mean_word_length': 4.099822799763733, 'pattern_counts': {'":': 0, '<': 149, '<?xml version=': 0, '>': 179, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 13}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1578051', 'n_tokens_mistral': 4282, 'n_tokens_neox': 4308, 'n_words': 333}