Десять тысяч слов + 33 изображения для изучения основных принципов архитектуры OpenFeign.
Десять тысяч слов + 33 изображения для изучения основных принципов архитектуры OpenFeign.

Привет всем, я Санью~~

Давным-давно я написал две статьи об архитектурных принципах OpenFeign и Ribbon, двух основных компонентах Spring Cloud.

Но, честно говоря, с моей нынешней точки зрения, структуру и содержание этих двух статей можно улучшить.

Так уж получилось, что недавно я запланировал буклет об архитектурных принципах каждого компонента SpringCloud.

Поэтому я воспользуюсь этой возможностью и перепишу эти две статьи, чтобы восполнить недостатки предыдущих статей.

В этой статье сначала поговорим об основных архитектурных принципах OpenFeign.

Вся статья условно разделена на следующие четыре части:

Первая часть, отделенная от Spring Cloud, как выглядит оригинальный Feign?

Часть 2. Каковы основные компоненты Feign и как выглядит вся ссылка выполнения?

Часть 3. Как SpringCloud интегрирует Feign в свою собственную экосистему?

Часть 4. OpenFeign имеет несколько методов настройки. Каковы приоритеты различных методов настройки?

Хорошо, без лишних слов, давайте перейдем непосредственно к теме, чтобы изучить основные принципы архитектуры OpenFeign.

Каким был оригинальный Feign?

В повседневной разработке использовать Feign очень просто, всего три шага.

Шаг 1. Введение зависимостей

Язык кода:javascript
копировать
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
     <version>2.2.5.RELEASE</version>
</dependency>

Шаг 2:В класс начальной загрузки добавьте@EnableFeignClientsаннотация

Язык кода:javascript
копировать
@SpringBootApplication
@EnableFeignClients
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

Шаг 3. Напишите интерфейс FeignClient.

Язык кода:javascript
копировать
@FeignClient(name = "order")
@RequestMapping("/order")
public interface OrderApiClient {

    @GetMapping
    Order queryOrder(@RequestParam("orderId") Long orderId);

}

Позже, когда мы захотим использовать,Просто нужно сделать инъекциюOrderApiClientобъект на нем

Хотя его легко использовать, это не оригинальный способ использования Feign, а способ использования Feign после его интеграции в SpringCloud.

Первоначально исходный код Feign был открыт Netflix.

Позже Spring Cloud инкапсулировал Feign и интегрировал его в свою собственную экосистему, что упростило использование Feign.

А также дал ему более продвинутое имя OpenFeign.

В следующей статье нет четкого различия между значениями Feign и OpenFeign. Вам просто нужно знать, что это значит.

У Feign есть собственный способ его использования, а также аналогичные аннотации, относящиеся к Spring MVC, как показано ниже:

Язык кода:javascript
копировать
public interface OrderApiClient {

    @RequestLine("GET /order/{orderId}")
    Order queryOrder(@Param("orderId") Long orderId);

}

OrderApiClientОбъекты необходимо передавать вручнуюFeign.builder()создать

Язык кода:javascript
копировать
public class FeignDemo {

    public static void main(String[] args) {
        OrderApiClient orderApiClient = Feign.builder()
                .target(OrderApiClient.class, "http://localhost:8088");
        orderApiClient.queryOrder(9527L);
    }

}

Суть Feign: динамический прокси + Семь основных компонентов

Я полагаю, что каждый, кто хоть немного знаком с Feign, знает, что нижний уровень Feign на самом деле основан на динамическом прокси-сервере JDK.

такFeign.builder()Последняя конструкция — прокси-объект.

Когда Feign создает динамический прокси, он анализирует аннотации и параметры метода.

Для получения Http-запросов необходимы базовые параметры и соответствие между этими параметрами и параметрами метода.

Например, URL-адрес HTTP-запроса, тело запроса — параметр метода, заголовок запроса — параметр метода и т. д.

Позже, при построении Http-запроса, вы будете знать, какая часть данных в Http-запросе соответствует пути запроса и первому параметру метода.

При вызове метода динамического прокси Feign соберет проанализированные выше базовые параметры и входные параметры метода Http-запроса в Http-запрос.

Затем отправьте HTTP-запрос, получите ответ, а затем преобразуйте содержимое тела ответа в соответствующий тип в соответствии с типом содержимого ответа.

Это общий принцип Feign.

В течение всего процесса генерации и вызова динамического прокси Feign необходимо полагаться на некоторые основные компоненты Feign для координации.

Как показано на рисунке ниже, показаны некоторые основные компоненты Feign.

Доступ к этим основным компонентам можно получить черезFeign.builder()Сделать замену

Поскольку компонентов много, здесь я выберу несколько важных и расскажу о них с вами.

1、Contract

Я говорил об этом раньше Когда Feign создает динамический прокси, он анализирует аннотации и параметры метода.,получатьHttpЗапрос требует основных параметров

Функция этого интерфейса контракта — проведение анализа.

Реализация Contract по умолчанию анализирует собственные аннотации Feign.

При анализе для каждого метода создается объект MethodMetadata.

MethodMetadata инкапсулирует основные параметры, необходимые для HTTP-запросов, и соответствие между этими параметрами и параметрами метода.

Когда SpringCloud интегрировал Feign, чтобы Feign распознавал аннотации Spring MVC, он реализовал сам интерфейс Contract.

2、Encoder

По названию также можно сказать, что он фактически используется для кодирования.

Конкретная функция заключается в сериализации параметров метода, соответствующих телу запроса, в массив байтов.

Реализация кодировщика Feign по умолчанию поддерживает только типы параметров метода, соответствующие телу запроса, в виде строковых и байтовых массивов.

Если это другие типы,Например, тип параметра метода, соответствующий телу запроса, имеет видAddOrderRequest.classтип,В это времяниктоюридическая параAddOrderRequestсериализация объектов

Это затрудняет использование этого кодировщика по умолчанию.

С тех пор Spring реализовал интерфейс Encoder.

Объект типа параметра метода, соответствующий любому телу запроса, может быть сериализован в массив байтов.

3、Decoder

Функция декодера прямо противоположна функции кодировщика.

Кодировщик сериализует параметры метода, соответствующие телу запроса, в массив байтов.

Декодер фактически десериализует тело ответа из потока байтов в объект типа возвращаемого значения метода.

По умолчанию Decoder аналогичен Encoder. Он поддерживает только десериализацию в массивы байтов или строки.

Поэтому Spring также реализует декодер для расширения его функциональности.

Поток байтов, соответствующий телу ответа, может быть десериализован в любой объект типа возвращаемого значения.

4、Client

Из параметров и возвращаемых значений методов интерфейса видно, что на самом деле это тот компонент, который в конечном итоге используется динамическим прокси-объектом для выполнения Http-запросов.

Реализация по умолчанию осуществляется через HttpURLConnection, предоставляемый JDK.

В дополнение к этому значению по умолчанию Feign также предоставляет реализацию на основе HttpClient и OkHttp.

в проекте,Чтобы заменить реализацию по умолчанию,Просто введите соответствующие зависимости,ЗданиеFeign.builder()Просто устанавливайте его время от времени

Среда SpringCloud будет автоматически настроена в соответствии с введенными зависимостями.

В дополнение к трем вышеперечисленным реализациям,Самое главное, конечно, то, что оно основано набалансировка нагрузкиРеализация

Ниже приведена основная реализация, используемая OpenFeign для интеграции ленты.

Этот Клиент получит информацию об экземпляре службы с ленты на основе имени службы, то есть IP-адреса и порта.

После этого экземпляру службы будет отправлен HTTP-запрос через IP-адрес и порт.

5、InvocationHandlerFactory

Я считаю, что каждый должен быть знаком с InvoctionHandler.

Для динамических агентов JDK необходимо реализовать InvoctionHandler для создания динамических агентов.

Реализация метода вызова InvoctionHandler является основной логикой динамического прокси.

InvocationHandlerFactory на самом деле является фабрикой, которая создает InvocationHandler.

Таким образом, вы можете догадаться, что InvokeHandler, созданный с помощью InvoctionHandlerFactory, должен быть основной логикой выполнения динамического прокси Feign.

Реализация InvoctionHandlerFactory по умолчанию следующая:

Эта реализация по умолчанию также используется по умолчанию в среде SpringCloud.

Итак, перейдём непосредственно к классу реализации FeignInvocationHandler из InfectionHandler.

Из реализации видно, что в дополнение к некоторым методам класса Object в конечном итоге будет вызван метод вызова метода MethodHandler, соответствующий этому методу.

Так что обратите внимание,этотMethodHandlerСразуИнкапсулирует основную логику симуляции выполнения Http-вызовов.,очень важно,Будет упомянуто позже

Хотя SpringCloud по умолчанию использует реализацию по умолчанию, в конечном итоге используется FeignInvocationHandler.

Но когда другие фреймворки интегрируют экосистему SpringCloud, чтобы адаптироваться к OpenFeign, они иногда сами реализуют InvoctionHandler.

Например, распространенные фреймворки предохранителей с ограничением тока Hystrix и Sentinel реализовали свой собственный InvokeHandler.

Таким образом, такие операции, как ограничение тока и понижение версии, могут выполняться до и после выполнения MethodHandler, то есть до и после вызова интерфейса Http.

6、RequestInterceptor

RequestInterceptor на самом деле является интерфейсом перехвата перед отправкой запроса.

Через этот интерфейс содержимое HTTP-запроса изменяется перед отправкой HTTP-запроса.

Например, мы можем установить некоторые общедоступные параметры, необходимые интерфейсу, такие как токен аутентификации и так далее.

Язык кода:javascript
копировать
@Component
public class TokenRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("token", «значение токена»);
    }

}

7、Retryer

Это компонент повтора, реализация по умолчанию следующая.

По умолчанию максимальное количество повторов составляет 5 раз.

В SpringCloud приведенная выше реализация не используется, но используется следующая реализация

Поэтому Spring Cloud не будет повторять попытку по умолчанию.

Маленький Подвести итог

В этом разделе в основном представлены семь основных компонентов Feign и соответствующая реализация расширения Spring.

Для вашего удобства я составил следующую таблицу

интерфейс

эффект

Симулировать реализацию по умолчанию

Весенняя реализация

Contract

Анализ аннотаций и параметров метода и сопоставление параметров HTTP-запроса с параметрами метода.

Contract.Default

SpringMvcContract

Encoder

Сериализуйте параметры метода, соответствующие телу запроса, в массив байтов.

Encoder.Default

SpringEncoder

Decoder

Десериализовать поток байтов тела ответа в объект типа возвращаемого значения метода.

Decoder.Default

SpringDecoder

Client

Отправить HTTP-запрос

Client.Default

LoadBalancerFeignClient

InvocationHandlerFactory

Фабрика InvokeHandler, логика динамического прокси-сервера

InvocationHandlerFactory.Default

никто

RequestInterceptor

Прежде чем отправлять HTTP-запрос, перехватите и измените содержимое HTTP-запроса.

никто

никто

Retryer

Повторить компонент

Retryer.Default

никто

Помимо этих, есть и другие компоненты, которые здесь не упомянуты.

Например, уровень журнала Logger.Level, вывод журнала Logger, если вам интересно, вы можете проверить это самостоятельно.

Анализ основного принципа работы Feign

В предыдущем разделе говорилось об основных компонентах Feign. В этом разделе мы поговорим об основном принципе работы Feign, который в основном разделен на две части:

  • динамический проксигенерироватьпринцип
  • Процесс выполнения вызова Feign Http

1. Принцип динамической генерации агентов

Здесь я сначала возьму демонстрационный код оригинального использования Feign, описанного выше.

Язык кода:javascript
копировать
public class FeignDemo {

    public static void main(String[] args) {
        OrderApiClient orderApiClient = Feign.builder()
                .target(OrderApiClient.class, "http://localhost:8088");
        orderApiClient.queryOrder(9527L);
    }

}

Это видно из демо,наконец прошлоFeign.builder().target(xx)получатьприезжатьдинамический проксииз

Логика выполнения приведенного выше кода следующая:

Наконец, будет вызван метод newInstance ReflectiveFeign для создания динамического прокси-объекта.

ReflectiveFeign внутренне настраивает некоторые из основных компонентов, упомянутых ранее.

Далее давайте посмотрим на метод newInstance.

Этот метод в основном делает две вещи:

Первое, что нужно сделать, это проанализировать интерфейс и построить обработчик метода, соответствующий каждому методу.

MethodHandler особенно напомнил мне, когда я ранее говорил о InvoctionHandlerFactory.

Динамический прокси (FeignInvoctionHandler) в конечном итоге вызовет MethodHandler для обработки Http-вызова от Feign.

При разборе интерфейса,Ранее упомянутый контракт будет использоваться для анализа параметров и аннотаций метода.,Генерироватьметодметаданные,Я не буду публиковать здесь свой код.

Во-вторых, необходимо создать InvoctionHandler через InvoctionHandlerFactory.

Затем создайте активный прокси-объект интерфейса.

ок, теперь мы фактически завершили процесс генерации динамического прокси.

такдинамический Логика генерации прокси очень проста. Всего несколько строк кода. Нарисуйте картинку. итог

2. Процесс выполнения вызова Feign Http

Я сказал это раньше,При вызове интерфейсдинамического прокси,проходитьInvoctionHandler(FeignInvoctionHandler),Наконец, он передается на выполнение методу вызова MethodHandler.

MethodHandler — это интерфейс, который в конечном итоге достигает реализации метода вызова своего класса реализации SynchronousMethodHandler.

Свойства в SynchronousMethodHandler — это некоторые из компонентов, о которых мы упоминали ранее.

Поскольку вся ссылка на выполнение вызова кода относительно длинная, я не буду здесь обрезать код. Если вам интересно, вы можете прочитать его самостоятельно.

Но здесь я нарисовал картинку, по которой можно примерно проанализировать весь процесс вызова Feign Http.

  • Прежде всего, как упоминалось ранее, введите FeignInvoctionHandler, найдите SynchronousMethodHandler, соответствующий методу, и вызовите метод вызова для его реализации.
  • После этого RequestTemplate создается на основе MethodMetadata и входных параметров метода. RequestTemplate инкапсулирует параметры Http-запроса. В ходе этого процесса, если существует тело запроса, оно будет сериализовано через Encoder.
  • Затем вызовите RequestInterceptor, перехватите и расширите RequestTemplate через RequestInterceptor и измените данные запроса.
  • Затем преобразуйте RequestTemplate в Request. Request фактически аналогичен RequestTemplate, а также инкапсулирует параметры Http-запроса.
  • Далее используйте Клиент для получения ответа на основе параметров HTTP-запроса, инкапсулированных в Request, Отправить HTTP-запрос.
  • Наконец, согласно декодеру, тело ответа десериализуется в объект типа возвращаемого значения метода и возвращает

Это процесс выполнения Http-вызова Feign.

Если есть настройка повтора, она также вступит в силу на этом этапе.

Как SpringCloud интегрирует Feign?

Когда SpringCloud интегрирует Feign, он в основном делится на две части.

  • Основные компоненты повторно реализованы для поддержки большего количества функций, связанных с экосистемой Spring Cloud.
  • Воляинтерфейсдинамический прокси-объект вводится в контейнер Spring

Первая часть перереализации основных компонентов уже упоминалась ранее, поэтому я не буду повторять ее здесь.

Что касается второй части, давайте поговорим о том, как Spring использует интерфейсдинамический. прокси-объект вводится в контейнер Springиз

1. Зарегистрируйте интерфейс FeignClient в Spring.

При использовании OpenFeign,необходимо добавить@EnableFeignClients

Эта аннотация является движком OpenFeign.

@EnableFeignClientsнаконецпроходить@Importаннотация ИмпортированFeignClientsRegistrar

FeignClientsRegistrarОсуществленныйImportBeanDefinitionRegistrar

такфинальныйSpringпри запускеизкогдапозвонюregisterBeanDefinitionsметод实现

之такпозвонюregisterBeanDefinitionsметод,да@Importаннотацияизэффект,Не уверениз Студенты могут посмотретьВзгляните на позы внедрения бобов в Spring. Сколько вы знаете?

финальныйвстреча走приезжатьregisterFeignClientsэтотметод

Хотя этот метод относительно длинный, в основном он выполняет следующие две задачи:

первое дело,сканирование@EnableFeignClientsрасположениедобрыйиз Пакеты и подпакеты(Если есть указанный пакет Сразу Сканируйте указанный пакет),Найти все добавленные@FeignClientаннотацияизинтерфейс,Сгенерируйте кучу BeanDefinitions

Этот BeanDefinition содержит такую ​​информацию, как этот интерфейс

Второе — зарегистрировать эти отсканированные интерфейсы в контейнере Spring.

При регистрации,Не тип интерфейса прямой регистрации,идаFeignClientFactoryBeanтип

хорошо,ко всему этому@EnableFeignClientsПроцесс запуска Сразувсе кончено

Хотя это очень долго,нодавесь@EnableFeignClientsНа самом деле Сразу Сделал только одну основную вещьизслучай

сканированиеприезжать所有издобавлять@FeignClientаннотацияизинтерфейс

а затем длякаждыйинтерфейсгенерироватьодинBeanтипдляFeignClientFactoryBeanизBeanDefinition

Наконец зарегистрирован в контейнере Spring

2. Секрет FeignClientFactoryBean

Упоминалось в предыдущем разделе,каждыйинтерфейс Все соответствуют одномуclassтипдляFeignClientFactoryBeanизBeanDefinition

как показано выше,FeignClientFactoryBeanдаодинFactoryBean

иFeignClientFactoryBeanиз Эти свойства,Он устанавливается при создании BeanDefinition.

И этот атрибут типа представляет собой тип интерфейса.

Благодаря внедрению FactoryBean,Итак, во время запуска Spring,一定дляпозвонюgetObjectметодполучатьнастоящийизBeanобъект

Я не буду говорить об эффекте FactoryBean.,Не уверениз Маленький Партнер такжеда Вы можете взглянутьВзгляните на позы внедрения бобов в Spring. Сколько вы знаете?Эта статья

getObjectфинальныйвстреча走приезжатьgetTarget()метод

Из приведенного выше кода видно, что,финальныйвозвращатьсядавстречапроходитьFeign.builder()создатьдинамический проксиобъект

Единственное отличие состоит в том, что SpringCloud заменит стандартные компоненты Feign и реализует их самостоятельно.

В общем, Spring добавляет динамические прокси-объекты Feign в контейнер Spring через FactoryBean.

Различные методы настройки и соответствующие приоритеты OpenFeign.

Поскольку основные компоненты Feign можно заменить, как нам настроить наши собственные компоненты в среде Spring Cloud?

Но прежде чем говорить о конфигурации, давайте поговорим об операции изоляции конфигурации FeignClient.

В среде Spring Cloud, чтобы изолировать разные клиенты Feign друг от друга.

Когда приложение запускается,Для каждого интерфейса FeignClient будет создан контейнер Spring.,Далее я назову этот контейнер контейнером FeignClient.

Эти контейнеры FeignClient Spring имеют один и тот же родительский контейнер, который является контейнером, созданным при запуске проекта.

SpringCloudдамкаждыйFeignClientконтейнер添加один默认из КонфигурациядобрыйFeignClientsConfigurationКонфигурациядобрый

Этот класс конфигурации объявляет различные компоненты Feign.

Поэтому по умолчанию OpenFeign использует эти настроенные компоненты для создания прокси-объектов.

Зная, как настроить изоляцию, давайте рассмотрим конкретные методы настройки и соотношение приоритетов между ними.

1. Настройте с помощью атрибута defaultConfiguration, помеченного @EnableFeignClients.

Приведите пример,Например, я объявляю один вручнуюContractобъект,типдляMyContract

Язык кода:javascript
копировать
public class FeignConfiguration {
    
    @Bean
    public Contract contract(){
        return new MyContract();
    }
    
}

Внимание Внимание,здесьFeignConfigurationя не добавлял это@Configurationаннотация,Причина будет обсуждаться позже

Конфигурация на данный момент следующая:

Язык кода:javascript
копировать
@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)

послеэтот Конфигурациядобрыйвстреча被加приезжатькаждыйFeignClientконтейнерсередина,такэтот Конфигурация Это эффективно для всех FeignClients.

И приоритет выше, чем приоритет, настроенный по умолчанию.

напримерэтотпример Сразувстреча使得FeignClientиспользуйте оператор iизMyContract,и不даFeignClientsConfigurationсерединазаявлениеизSpringMvcContract

2. Настройте с помощью атрибута конфигурации, помеченного @FeignClient.

вернуть услугувышеизFeignConfigurationКонфигурациядобрый Пример,Можетпроходить@FeignClientаннотация Конфигурация

Язык кода:javascript
копировать
@FeignClient(name = "order", configuration = FeignConfiguration.class)

в это времяэтот Конфигурациядобрыйвстреча被加приезжатьСобственный контейнер FeignClient.середина,Уведомлениеда Собственный контейнер FeignClient.

так Этот вид КонфигурацияизэффектобъемдаМой собственный FeignClient

иЭтот вид Конфигурацияизприоритетдабольше, чем@EnableFeignClientsаннотация Конфигурацияизприоритет

3. Настроить в контейнере, запущенном проектом

Как упоминалось ранее, поскольку родительским контейнером всех контейнеров FeignClient является контейнер, запущенный проектом

Таким образом, вы можете поместить конфигурацию в контейнер, запущенный этим проектом.

вернуть услугуFeignConfigurationНапример,плюс@Configurationаннотация,Пусть контейнер, запущенный проектом, успешно просканируется.

Этот вид КонфигурацияизПриоритет выше, чем у всех ранее упомянутых приоритетов конфигурации.

иЭто эффективно для всех FeignClients.

так,этот Сразудадля什么使用аннотация Конфигурацияпочему Конфигурациядобрый Невозможно добавить@Configurationаннотацияизпричина,Потому что как только он сканируется контейнером, запущенным проектом,Эта конфигурация будет действовать для всех FeignClients.,И приоритет самый высокий,Это приведет к сбою другой конфигурации.,Конечно, вы также можете добавить@Configurationаннотация,Но его не должен сканировать контейнер, запущенный проектом.

4. Конфигурационный файл

В дополнение к трем вышеупомянутым конфигурациям методов кодирования OpenFeign также поддерживает настройку через файлы конфигурации.

И он также поддерживает действие на все FeignClients и действие на один FeignClient одновременно.

Конфигурация действительна для всех FeignClients:

Язык кода:javascript
копировать
feign:
  client:
    config:
      default: # default Представляет глобальный эффект
        contract: com.sanyou.feign.MyContract

Эффективная конфигурация для одного FeignClient:

Язык кода:javascript
копировать
feign:
  client:
    config:
      order: # конкретное название службы
        contract: com.sanyou.feign.MyContract

По умолчанию этот метод файла конфигурации имеет наивысший приоритет.

нодаесли ты Конфигурациядокументсередина Воля Конфигурацияэлементfeign.client.default-to-propertiesустановлен наfalseизразговаривать,Файл конфигурации имеет самый низкий приоритет.

Язык кода:javascript
копировать
feign:
  client:
    default-to-properties: false
Маленький Подвести итог

В этом разделе Подвести итог представлены 4 способа OpenFeign, а также их приоритет и диапазон эффектов.

Нарисуй картинку итог

Если вы по-прежнему сталкиваетесь с некоторыми проблемами приоритета во время конкретного использования, вы можете отладить эту часть исходного кода, чтобы увидеть, какая конфигурация вступит в силу.

Подвести итог

На этом этапе мы наконец закончили говорить об основных архитектурных принципах OpenFeign.

Это еще одна красноречивая статья на 10 000 слов.

Поскольку OpenFeign — это всего лишь фреймворк, здесь нет сложного механизма.

Таким образом, вся статья больше сосредоточена на исходном коде.

Я не знаю, как ты выглядишь и чувствуешь

Если вам хорошо, ставьте лайк, смотрите, собирайте и делитесь с теми, кому это нужно.

Ваша поддержка — моя самая большая мотивация для обновлений, спасибо!

Дополнительные статьи серии SpringCloud можно просмотреть в строке меню официального аккаунта.

Ладно, на этом статья закончена, увидимся в следующий раз, пока!

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose