最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)grpc框架的示例

 更新時(shí)間:2025年09月23日 09:59:01   作者:TanYYF  
本文主要介紹了gRPC框架及其與ProtocolBuffers的結(jié)合,用于構(gòu)建分布式系統(tǒng),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1.grpc簡介

官方地址:https://grpc.io/docs/what-is-grpc/introduction/

在gRPC中,客戶機(jī)應(yīng)用程序可以直接調(diào)用不同機(jī)器上的服務(wù)器應(yīng)用程序上的方法,就像它是本地對(duì)象一樣,使您更容易創(chuàng)建分布式應(yīng)用程序和服務(wù)。與許多RPC系統(tǒng)一樣,gRPC基于定義服務(wù)的思想,指定可以遠(yuǎn)程調(diào)用的方法及其參數(shù)和返回類型。在服務(wù)器端,服務(wù)器實(shí)現(xiàn)這個(gè)接口,并運(yùn)行g(shù)RPC服務(wù)器來處理客戶端調(diào)用。在客戶端,客戶端有一個(gè)存根(在某些語言中稱為客戶端),它提供與服務(wù)器相同的方法

gRPC客戶端和服務(wù)器可以在各種環(huán)境中運(yùn)行并相互通信——從Google內(nèi)部的服務(wù)器到您自己的桌面——并且可以用任何gRPC支持的語言編寫。因此,例如,您可以輕松地用Java創(chuàng)建gRPC服務(wù)器,用Go、Python或Ruby創(chuàng)建客戶端。

2.Protocol Buffers

官方地址:https://protobuf.dev/overview/

默認(rèn)情況下,gRPC使用Protocol Buffers,這是Google用于序列化結(jié)構(gòu)化數(shù)據(jù)的成熟開源機(jī)制(盡管它可以與JSON等其他數(shù)據(jù)格式一起使用)
Protocol Buffers是一種語言無關(guān)、平臺(tái)無關(guān)的可擴(kuò)展機(jī)制,用于序列化結(jié)構(gòu)化數(shù)據(jù)。
它類似于JSON,只是更小更快,并且生成本地語言綁定。您只需定義一次數(shù)據(jù)的結(jié)構(gòu)化方式,然后就可以使用特殊生成的源代碼輕松地將結(jié)構(gòu)化數(shù)據(jù)寫入和讀取到各種數(shù)據(jù)流,并使用各種語言。

協(xié)議緩沖區(qū)是定義語言(在.proto文件中創(chuàng)建)、proto編譯器為與數(shù)據(jù)交互而生成的代碼、特定于語言的運(yùn)行時(shí)庫以及寫入文件(或通過網(wǎng)絡(luò)連接發(fā)送)的數(shù)據(jù)的序列化格式的組合

3.創(chuàng)建maven項(xiàng)目grpc-demo

3.1 編寫maven 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>grpc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--grpc版本 -->
        <grpc.version>1.60.2</grpc.version>
    </properties>

    <dependencies>
        <!-- grpc 需要的依賴-->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>${grpc.version}</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>${grpc.version}</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>${grpc.version}</version>
        </dependency>

    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <!--它將{@code .proto}文件 生成java源代碼 -->
                            <goal>compile</goal>
                            <!--它將{@code .proto}文件 生成grpc java源代碼 -->
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <!-- 解決jar 包沖突、重復(fù)依賴、無效引用 -->
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>1.4.1</version>
                <executions>
                    <execution>
                        <id>enforce</id>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <requireUpperBoundDeps/>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3.2 在/src/main/目錄下創(chuàng)建 helloworld.proto文件

官方地址: https://gitcode.com/grpc/grpc-java/blob/master/examples/src/main/proto/helloworld.proto

// Copyright 2015 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

3.3 生成代碼

idea選中項(xiàng)目pom.xml-右鍵->run maven -> Plugins->protobuf-maven-plugin->protobuf:compile
或者進(jìn)入到項(xiàng)目目錄直接執(zhí)行mvn命令:

#生成protobuf代碼
mvn protobuf:compile
#生成grpc代碼
mvn protobuf:compile-custom

生成成功的代碼如截圖,將代碼拷貝到項(xiàng)目對(duì)應(yīng)的位置:

代碼拷貝到項(xiàng)目截圖:

4.代碼編寫

4.1 HelloWordServer服務(wù)端編寫

package io.grpc.examples.helloworld2;

import io.grpc.Grpc;
import io.grpc.InsecureServerCredentials;
import io.grpc.Server;
import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.stub.StreamObserver;

import java.io.IOException;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @Author tanyong
 * @Version HelloWordServer v1.0.0 2024/4/2 11:21 $$
 */
public class HelloWordServer {
    private static int port = 50052;

    /**
     * grpc服務(wù)實(shí)例
     */
    private Server server;

    /**
     * 啟動(dòng) grpc服務(wù)
     *
     * @throws IOException
     */
    public void start() throws IOException {

        server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
                // 添加業(yè)務(wù)處理類
                .addService(new GreeterImpl(port))
                .build()
                .start();
        // 注冊了一個(gè)JVM關(guān)閉鉤子(Shutdown Hook),當(dāng)Java虛擬機(jī)(JVM)即將關(guān)閉時(shí)(無論是正常退出還是非正常退出,如接收到操作系統(tǒng)中斷信號(hào))當(dāng)JVM關(guān)閉時(shí),所有已注冊的關(guān)閉鉤子都將被依次調(diào)用
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                // Use stderr here since the logger may have been reset by its JVM shutdown hook.
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                try {
                    // 優(yōu)雅地停止gRPC服務(wù)器實(shí)例
                    HelloWordServer.this.stop();
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
                System.err.println("*** server shut down");
            }
        });
    }

    /**
     * 停止grpc 實(shí)例
     *
     * @throws InterruptedException
     */
    public void stop() throws InterruptedException {
        if (Objects.nonNull(server)) {
            // 發(fā)起服務(wù)器的關(guān)閉流程,不再接受新的連接和請求,但允許現(xiàn)有連接繼續(xù)完成請求處理
            server.shutdown()
                    // 給予服務(wù)器最長30秒的時(shí)間去完成所有待處理的工作,超過這個(gè)時(shí)間限制,程序?qū)⒗^續(xù)執(zhí)行后續(xù)邏輯,即使服務(wù)器還有任務(wù)未完成
                    // 這樣設(shè)計(jì)有助于在應(yīng)用退出時(shí)確保資源得到釋放,同時(shí)也能防止因某些原因?qū)е碌拈L時(shí)間無法關(guān)閉的問題。
                    .awaitTermination(30, TimeUnit.SECONDS);
        }

    }

    /**
     * 確保主線程或者其他調(diào)用者線程會(huì)在服務(wù)器完全關(guān)閉之前保持等待狀態(tài)。
     * 在主線程上等待終止,因?yàn)間rpc庫使用守護(hù)線程
     *
     * @throws InterruptedException
     */
    public void blockUntilShutdown() throws InterruptedException {
        if (Objects.nonNull(server)) {
            server.awaitTermination();
        }
    }

    /**
     * 業(yè)務(wù)處理類
     */
    public static class GreeterImpl extends GreeterGrpc
            .GreeterImplBase {

        private final int port;

        public GreeterImpl(int port) {
            this.port = port;
        }

        /**
         * @param request
         * @param responseObserver 這是gRPC提供的響應(yīng)觀察者對(duì)象,用于向客戶端發(fā)送響應(yīng)。服務(wù)端通過調(diào)用其方法將響應(yīng)數(shù)據(jù)發(fā)送給客戶端。
         */
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + request.getName() + this.port).build();
            try {
                Thread.sleep(500 + new Random().nextInt(1000));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 向客戶端發(fā)送響應(yīng)數(shù)據(jù),即將創(chuàng)建好的 reply 對(duì)象推送給客戶端。
            responseObserver.onNext(reply);
            // 表示響應(yīng)已經(jīng)結(jié)束,沒有更多的數(shù)據(jù)要發(fā)送給客戶端。
            responseObserver.onCompleted();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final HelloWordServer helloWordServer = new HelloWordServer();
        helloWordServer.start();
        helloWordServer.blockUntilShutdown();
    }
}

4.2 自定負(fù)載均衡解析器編寫

HelloWordConstants.java常量:

public interface HelloWordConstants {
    String SCHEME = "example";
    String SERVICE_NAME = "lb.example.grpc.io";
}

負(fù)載均衡解析器LoadBalanceNameResolver.java

package io.grpc.examples.helloworld2;

import io.grpc.EquivalentAddressGroup;
import io.grpc.NameResolver;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author tanyong
 * @Version LoadBalanceNameResolver v1.0.0 2024/4/2 16:59 $$
 */
public class LoadBalanceNameResolver extends NameResolver {

    private Listener2 listener;

    private List<InetSocketAddress> socketAddressList;
    private String serviceName;

    private final Map<String, List<InetSocketAddress>> addrStore = new HashMap<>();

    public LoadBalanceNameResolver(List<InetSocketAddress> socketAddressList, String serviceName) {
        this.socketAddressList = socketAddressList;
        this.serviceName = serviceName;
        addrStore.put(serviceName, socketAddressList);

    }

    @Override
    public void start(Listener2 listener) {

        this.listener = listener;
        this.resolve();
    }

    @Override
    public void refresh() {
        this.resolve();
    }

    /**
     * 返回用于對(duì)服務(wù)器連接進(jìn)行身份驗(yàn)證的權(quán)限。它必須來自受信任的來源,因?yàn)槿绻麢?quán)限被篡改,rpc可能會(huì)被發(fā)送給攻擊者,這可能會(huì)泄露敏感的用戶數(shù)據(jù)。
     * 實(shí)現(xiàn)必須在不阻塞的情況下生成它,通常是在線生成,并且必須保持它不變。從同一工廠使用相同參數(shù)創(chuàng)建的namesolvers必須返回相同的權(quán)限。
     * 自:
     *
     * @return
     */
    @Override
    public String getServiceAuthority() {
        return "ok";
    }

    @Override
    public void shutdown() {

    }

    /**
     * 解析服務(wù)器地址
     */
    private void resolve() {
        List<InetSocketAddress> addresses = addrStore.get(serviceName);
        List<EquivalentAddressGroup> equivalentAddressGroup = addresses.stream().map(this::toSocketAddress)
                .map(Arrays::asList)
                .map(this::addrToEquivalentAddressGroup)
                .collect(Collectors.toList());
        ResolutionResult resolutionResult = ResolutionResult.newBuilder()
                .setAddresses(equivalentAddressGroup)
                .build();

        // 處理已解析地址和屬性的更新
        this.listener.onResult(resolutionResult);

    }

    private SocketAddress toSocketAddress(InetSocketAddress address) {
        return new InetSocketAddress(address.getHostName(), address.getPort());
    }

    private EquivalentAddressGroup addrToEquivalentAddressGroup(List<SocketAddress> addrList) {
        return new EquivalentAddressGroup(addrList);
    }
}

負(fù)載均衡解析器提供者LoadBalanceNameResolverProvider.java

package io.grpc.examples.helloworld2;

import io.grpc.NameResolver;
import io.grpc.NameResolverProvider;

import java.net.InetSocketAddress;
import java.net.URI;
import java.util.List;

/**
 * @Author tanyong
 * @Version LoadBalanceNameResolverProvider v1.0.0 2024/4/3 9:56 $$
 */
public class LoadBalanceNameResolverProvider extends NameResolverProvider {

    private final List<InetSocketAddress> socketAddressList;

    public LoadBalanceNameResolverProvider(List<InetSocketAddress> socketAddressList) {
        this.socketAddressList = socketAddressList;
    }


    @Override
    protected boolean isAvailable() {
        return true;
    }

    @Override
    protected int priority() {
        return 5;
    }

    @Override
    public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
        return new LoadBalanceNameResolver(socketAddressList, HelloWordConstants.SERVICE_NAME);
    }

    @Override
    public String getDefaultScheme() {
        return HelloWordConstants.SCHEME;
    }
}

4.3 客戶端HelloWordClient.java

package io.grpc.examples.helloworld2;

import io.grpc.*;
import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author tanyong
 * @Version HellowordClient v1.0.0 2024/4/2 16:33 $$
 */
public class HelloWordClient {

    /**
     * 客戶端對(duì)服務(wù)Greeter進(jìn)行同步rpc調(diào)用 blockingStub
     */
    private final GreeterGrpc.GreeterBlockingStub blockingStub;


    public HelloWordClient(Channel channel) {
        // 創(chuàng)建一個(gè)新的阻塞式Stub,支持對(duì)服務(wù)的一元和流輸出調(diào)用
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void greet(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();

        HelloReply response;
        try {
            // 設(shè)置此次RPC調(diào)用的響應(yīng)超時(shí)時(shí)間為1秒
            response = blockingStub.withDeadlineAfter(1, TimeUnit.SECONDS).sayHello(request);
            System.out.println(response.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 服務(wù)段連接地址
        List<InetSocketAddress> addressList = Arrays.asList(new InetSocketAddress("127.0.0.1", 50052),
                new InetSocketAddress("127.0.0.1", 50053));

        // 注冊 NameResolverProvider
        NameResolverRegistry.getDefaultRegistry().register(new LoadBalanceNameResolverProvider(addressList));
        // 符合namesolver的有效URI
        String target = String.format("%s:///%s", HelloWordConstants.SCHEME, HelloWordConstants.SERVICE_NAME);


        // 創(chuàng)建channel
        ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
                .defaultLoadBalancingPolicy("round_robin")
                // 使用明文連接到服務(wù)器。默認(rèn)情況下,將使用安全連接機(jī)制,如TLS。
                // 應(yīng)僅用于測試或API的使用或交換的數(shù)據(jù)不敏感的API。
                .usePlaintext()
                .disableRetry()
                .build();

        try {
            HelloWordClient client = new HelloWordClient(channel);
            long current = System.currentTimeMillis();
            for (int i = 0; i < 10; i++) {
                Thread.sleep(5000);
                client.greet("測試");
            }
            System.out.println(System.currentTimeMillis() - current);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 關(guān)閉channel
            channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
        }

    }
}

到此這篇關(guān)于Java實(shí)現(xiàn)grpc框架的示例的文章就介紹到這了,更多相關(guān)Java grpc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis-plus3.0.1枚舉返回為null解決辦法

    mybatis-plus3.0.1枚舉返回為null解決辦法

    這篇文章主要介紹了mybatis-plus3.0.1枚舉返回為null解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • SpringAI?Agent開發(fā)秘籍如何讓javaer也可以用上Agent?Skills

    SpringAI?Agent開發(fā)秘籍如何讓javaer也可以用上Agent?Skills

    文章介紹了如何使用SpringA和Skills構(gòu)建一個(gè)代碼評(píng)審應(yīng)用,通過實(shí)戰(zhàn)示例展示如何利用SpringAI和大模型實(shí)現(xiàn)零配置的代碼評(píng)審功能,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • java項(xiàng)目新建遇到的兩個(gè)問題解決

    java項(xiàng)目新建遇到的兩個(gè)問題解決

    創(chuàng)建一個(gè)新的Java項(xiàng)目可以通過多種方式進(jìn)行,包括使用集成開發(fā)環(huán)境(IDE)或手動(dòng)創(chuàng)建,下面這篇文章主要給大家介紹了關(guān)于java項(xiàng)目新建遇到的兩個(gè)問題,需要的朋友可以參考下
    2024-06-06
  • Spring依賴注入DI之三種依賴注入類型詳解

    Spring依賴注入DI之三種依賴注入類型詳解

    這篇文章主要介紹了Spring依賴注入DI之三種依賴注入類型詳解,通過 @Autowired 注解,字段注入的實(shí)現(xiàn)方式非常簡單而直接,代碼的可讀性也很強(qiáng),事實(shí)上,字段注入是三種注入方式中最常用、也是最容易使用的一種,需要的朋友可以參考下
    2023-09-09
  • Spring Data分頁與排序的實(shí)現(xiàn)方法

    Spring Data分頁與排序的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Spring Data分頁與排序的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Java中如何執(zhí)行多條shell/bat命令

    Java中如何執(zhí)行多條shell/bat命令

    這篇文章主要介紹了Java中如何執(zhí)行多條shell/bat命令的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Eclipse 出現(xiàn)A configuration with this name already exists問題解決方法

    Eclipse 出現(xiàn)A configuration with this name already exists問題解決方

    這篇文章主要介紹了Eclipse 出現(xiàn)A configuration with this name already exists問題解決方法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Java線程創(chuàng)建的5種寫法詳解

    Java線程創(chuàng)建的5種寫法詳解

    這段文章詳細(xì)解釋了線程與進(jìn)程的關(guān)系、線程狀態(tài)、線線程創(chuàng)建的幾種寫法、常見面試題以及高耦合與低耦合的概念,通過這些內(nèi)容,讀者可以全面了解線程的基礎(chǔ)知識(shí)及其在編程中的應(yīng)用,需要的朋友可以參考下
    2026-05-05
  • java中的數(shù)學(xué)計(jì)算函數(shù)的總結(jié)

    java中的數(shù)學(xué)計(jì)算函數(shù)的總結(jié)

    這篇文章主要介紹了java中的數(shù)學(xué)計(jì)算函數(shù)的總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 使用Java?Executors創(chuàng)建線程池的9種方法

    使用Java?Executors創(chuàng)建線程池的9種方法

    文章主要介紹了?Java?中Executors類創(chuàng)建線程池的?9?種方法,每種方法都詳細(xì)闡述了實(shí)現(xiàn)原理、源代碼分析、參數(shù)解釋、實(shí)現(xiàn)過程、特性和使用場景,感興趣的小伙伴跟著小編一起來看看吧
    2024-11-11

最新評(píng)論

武陟县| 余干县| 光泽县| 巴马| 宁远县| 高碑店市| 阿合奇县| 启东市| 南昌县| 武川县| 南乐县| 获嘉县| 江口县| 彰化县| 赤峰市| 丽江市| 剑河县| 永登县| 彭阳县| 绥化市| 新蔡县| 新兴县| 渝中区| 安宁市| 新平| 秦皇岛市| 若尔盖县| 丘北县| 将乐县| 福海县| 特克斯县| 泰兴市| 巧家县| 和顺县| 尉氏县| 定西市| 平南县| 铅山县| 潼南县| 卓尼县| 郑州市|