成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù),針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

在鼓樓等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需求定制設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,全網(wǎng)整合營(yíng)銷推廣,外貿(mào)網(wǎng)站建設(shè),鼓樓網(wǎng)站建設(shè)費(fèi)用合理。

1. 創(chuàng)建應(yīng)用程序 - 依賴項(xiàng)

在創(chuàng)建新應(yīng)用程序時(shí),你可以執(zhí)行一個(gè)Maven命令,該命令使用quarkus-maven-plugin。依賴項(xiàng)應(yīng)該在參數(shù)-Dextensions中聲明。

mvn io.quarkus:quarkus-maven-plugin:0.21.1:create \
    -DprojectGroupId=pl.piomin.services \
    -DprojectArtifactId=employee-service \
    -DclassName="pl.piomin.services.employee.controller.EmployeeController" \
    -Dpath="/employees" \
    -Dextensions="resteasy-jackson, hibernate-validator"

下面是我們pom.xml的結(jié)構(gòu):

<properties>
    <quarkus.version>0.21.1</quarkus.version>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencymanagement>
    <dependencies>
        <dependency>
            <groupid>io.quarkus</groupid>
            <artifactid>quarkus-bom</artifactid>
            <version>${quarkus.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencymanagement>
<build>
    <plugins>
        <plugin>
            <groupid>io.quarkus</groupid>
            <artifactid>quarkus-maven-plugin</artifactid>
            <version>${quarkus.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

對(duì)于使用輸入驗(yàn)證構(gòu)建簡(jiǎn)單的REST應(yīng)用程序,我們不需要太多模塊。您可能已經(jīng)注意到,我只聲明了兩個(gè)擴(kuò)展,這與下面pom.xml中的依賴項(xiàng)列表相同:

<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-resteasy-jackson</artifactid>
</dependency>
<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-hibernate-validator</artifactid>
</dependency>

2. 創(chuàng)建應(yīng)用程序 - 代碼

對(duì)于Spring Boot或Micronaut用戶來(lái)說(shuō),可能有點(diǎn)奇怪的是,沒(méi)有使用靜態(tài)代碼main方法的主運(yùn)行類。resource/controller類實(shí)際上就是主類。Quarkus的resource/controller類和方法應(yīng)該使用javax.ws.rs庫(kù)中的注解進(jìn)行標(biāo)記。

下面是employee-service的REST controller 的實(shí)現(xiàn):

@Path("/employees")
@Produces(MediaType.APPLICATION_JSON)
public class EmployeeController {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeController.class);

    @Inject
    EmployeeRepository repository;

    @POST
    public Employee add(@Valid Employee employee) {
        LOGGER.info("Employee add: {}", employee);
        return repository.add(employee);
    }

    @Path("/{id}")
    @GET
    public Employee findById(@PathParam("id") Long id) {
        LOGGER.info("Employee find: id={}", id);
        return repository.findById(id);
    }

    @GET
    public Set<employee> findAll() {
        LOGGER.info("Employee find");
        return repository.findAll();
    }

    @Path("/department/{departmentId}")
    @GET
    public Set<employee> findByDepartment(@PathParam("departmentId") Long departmentId) {
        LOGGER.info("Employee find: departmentId={}", departmentId);
        return repository.findByDepartment(departmentId);
    }

    @Path("/organization/{organizationId}")
    @GET
    public Set<employee> findByOrganization(@PathParam("organizationId") Long organizationId) {
        LOGGER.info("Employee find: organizationId={}", organizationId);
        return repository.findByOrganization(organizationId);
    }

}

我們使用CDI進(jìn)行依賴注入,使用SLF4J進(jìn)行日志記錄。 Controller類使用內(nèi)存存儲(chǔ)庫(kù)bean存儲(chǔ)和檢索數(shù)據(jù)。Repository bean使用CDI @ApplicationScoped注解,并注入controller:

@ApplicationScoped
public class EmployeeRepository {

    private Set<employee> employees = new HashSet&lt;&gt;();

    public EmployeeRepository() {
        add(new Employee(1L, 1L, "John Smith", 30, "Developer"));
        add(new Employee(1L, 1L, "Paul Walker", 40, "Architect"));
    }

    public Employee add(Employee employee) {
        employee.setId((long) (employees.size()+1));
        employees.add(employee);
        return employee;
    }

    public Employee findById(Long id) {
        Optional<employee> employee = employees.stream().filter(a -&gt; a.getId().equals(id)).findFirst();
        if (employee.isPresent())
            return employee.get();
        else
            return null;
    }

    public Set<employee> findAll() {
        return employees;
    }

    public Set<employee> findByDepartment(Long departmentId) {
        return employees.stream().filter(a -&gt; a.getDepartmentId().equals(departmentId)).collect(Collectors.toSet());
    }

    public Set<employee> findByOrganization(Long organizationId) {
        return employees.stream().filter(a -&gt; a.getOrganizationId().equals(organizationId)).collect(Collectors.toSet());
    }

}

最后一個(gè)組件是帶驗(yàn)證的實(shí)體類:

public class Employee {

    private Long id;
    @NotNull
    private Long organizationId;
    @NotNull
    private Long departmentId;
    @NotBlank
    private String name;
    @Min(1)
    @Max(100)
    private int age;
    @NotBlank
    private String position;

    // ... GETTERS AND SETTERS

}

3. 單元測(cè)試

對(duì)于大多數(shù)流行的Java框架,使用Quarkus進(jìn)行單元測(cè)試非常簡(jiǎn)單。如果您正在測(cè)試基于REST的web應(yīng)用程序,您應(yīng)該在pom.xml中包含以下依賴項(xiàng):

<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-junit5</artifactid>
    <scope>test</scope>
</dependency>
<dependency>
    <groupid>io.rest-assured</groupid>
    <artifactid>rest-assured</artifactid>
    <scope>test</scope>
</dependency>

讓我們分析一下來(lái)自organization-service(我們的另一個(gè)微服務(wù),以及employee-service和department-service)的測(cè)試類。測(cè)試類應(yīng)該用@QuarkusTest注釋。我們可以通過(guò)@Inject注解注入其他bean。其余部分是典型的JUnit和RestAssured—我們正在測(cè)試controller公開(kāi)的API方法。因?yàn)槲覀兪褂脙?nèi)存存儲(chǔ)庫(kù),所以除了服務(wù)間通信之外,我們不需要模擬任何東西(我們將在本文后面討論)。對(duì)于GET、POST方法,我們有一些積極的場(chǎng)景,還有一個(gè)不通過(guò)輸入驗(yàn)證的消極場(chǎng)景(testInvalidAdd)。

@QuarkusTest
public class OrganizationControllerTests {

    @Inject
    OrganizationRepository repository;

    @Test
    public void testFindAll() {
        given().when().get("/organizations").then().statusCode(200).body(notNullValue());
    }

    @Test
    public void testFindById() {
        Organization organization = new Organization("Test3", "Address3");
        organization = repository.add(organization);
        given().when().get("/organizations/{id}", organization.getId()).then().statusCode(200)
                .body("id", equalTo(organization.getId().intValue()))
                .body("name", equalTo(organization.getName()));
    }

    @Test
    public void testFindByIdWithDepartments() {
        given().when().get("/organizations/{id}/with-departments", 1L).then().statusCode(200)
                .body(notNullValue())
                .body("departments.size()", is(1));
    }

    @Test
    public void testAdd() {
        Organization organization = new Organization("Test5", "Address5");
        given().contentType("application/json").body(organization)
                .when().post("/organizations").then().statusCode(200)
                .body("id", notNullValue())
                .body("name", equalTo(organization.getName()));
    }

    @Test
    public void testInvalidAdd() {
        Organization organization = new Organization();
        given().contentType("application/json").body(organization).when().post("/organizations").then().statusCode(400);
    }

}

4. 服務(wù)間通信

由于Quarkus的目標(biāo)是在Kubernetes上運(yùn)行,因此它不提供任何對(duì)第三方服務(wù)發(fā)現(xiàn)(例如通過(guò)Consul 或Netflix Eureka)和與此發(fā)現(xiàn)集成的HTTP客戶機(jī)的內(nèi)置支持。然而,Quarkus為REST通信提供了專用的客戶端支持。要使用它,我們首先需要包括以下依賴性:

<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-rest-client</artifactid>
</dependency>

Quarkus基于MicroProfile REST客戶機(jī)提供聲明性REST客戶機(jī)。您需要?jiǎng)?chuàng)建一個(gè)帶有所需方法的接口,并使用@RegisterRestClient對(duì)其進(jìn)行注解。其他注解與服務(wù)器端非常相似。因?yàn)槟褂?code>@RegisterRestClient來(lái)標(biāo)記Quarkus,所以應(yīng)該知道這個(gè)接口作為REST客戶機(jī)可用于CDI注入。

@Path("/departments")
@RegisterRestClient
public interface DepartmentClient {

    @GET
    @Path("/organization/{organizationId}")
    @Produces(MediaType.APPLICATION_JSON)
    List<department> findByOrganization(@PathParam("organizationId") Long organizationId);

    @GET
    @Path("/organization/{organizationId}/with-employees")
    @Produces(MediaType.APPLICATION_JSON)
    List<department> findByOrganizationWithEmployees(@PathParam("organizationId") Long organizationId);

}

現(xiàn)在,讓我們看一下organization-service內(nèi)的controller類。與@Inject一起,我們需要使用@RestClient注解來(lái)正確地注入REST客戶機(jī)bean。之后,您可以使用接口方法來(lái)調(diào)用其他公開(kāi)的服務(wù)

@Path("/organizations")
@Produces(MediaType.APPLICATION_JSON)
public class OrganizationController {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrganizationController.class);

    @Inject
    OrganizationRepository repository;
    @Inject
    @RestClient
    DepartmentClient departmentClient;
    @Inject
    @RestClient
    EmployeeClient employeeClient;

    // ... OTHER FIND METHODS

    @Path("/{id}/with-departments")
    @GET
    public Organization findByIdWithDepartments(@PathParam("id") Long id) {
        LOGGER.info("Organization find: id={}", id);
        Organization organization = repository.findById(id);
        organization.setDepartments(departmentClient.findByOrganization(organization.getId()));
        return organization;
    }

    @Path("/{id}/with-departments-and-employees")
    @GET
    public Organization findByIdWithDepartmentsAndEmployees(@PathParam("id") Long id) {
        LOGGER.info("Organization find: id={}", id);
        Organization organization = repository.findById(id);
        organization.setDepartments(departmentClient.findByOrganizationWithEmployees(organization.getId()));
        return organization;
    }

    @Path("/{id}/with-employees")
    @GET
    public Organization findByIdWithEmployees(@PathParam("id") Long id) {
        LOGGER.info("Organization find: id={}", id);
        Organization organization = repository.findById(id);
        organization.setEmployees(employeeClient.findByOrganization(organization.getId()));
        return organization;
    }

}

通信中缺少的最后一個(gè)東西是目標(biāo)服務(wù)的地址。我們可以使用@RegisterRestClient注解的字段baseUri 來(lái)提供它們。然而,更好的解決方案似乎是將它們放在application.properties中。屬性名需要包含客戶端接口的完全限定名和后綴mp-rest/url

pl.piomin.services.organization.client.DepartmentClient/mp-rest/url=http://localhost:8090
pl.piomin.services.organization.client.EmployeeClient/mp-rest/url=http://localhost:8080

在前一節(jié)中,我已經(jīng)提到了單元測(cè)試和服務(wù)間通信。要測(cè)試與其他應(yīng)用程序通信的API方法,我們需要模擬REST客戶機(jī)。下面是為模擬示例創(chuàng)建了DepartmentClient。它應(yīng)該只在測(cè)試期間可見(jiàn),所以我們必須將它放在src/test/java中。如果我們用@Mock@RestClient注釋它,那么默認(rèn)情況下將自動(dòng)使用這個(gè)bean,而不是在src/main/java中定義的聲明性REST客戶機(jī)。

@Mock
@ApplicationScoped
@RestClient
public class MockDepartmentClient implements DepartmentClient {

    @Override
    public List<department> findByOrganization(Long organizationId) {
        return Collections.singletonList(new Department("Test1"));
    }

    @Override
    public List<department> findByOrganizationWithEmployees(Long organizationId) {
        return null;
    }

}

5. 監(jiān)測(cè)和記錄

我們可以輕松地使用Quarkus公開(kāi)健康檢查或API文檔。API文檔是使用OpenAPI/Swagger構(gòu)建的。Quarkus利用了 SmallRye項(xiàng)目中可用的庫(kù)。我們應(yīng)該在pom.xml中包含以下依賴項(xiàng):

<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-smallrye-openapi</artifactid>
</dependency>
<dependency>
    <groupid>io.quarkus</groupid>
    <artifactid>quarkus-smallrye-health</artifactid>
</dependency>

我們可以定義兩種類型的健康檢查:readiness 和liveness。有/health/ready/health/live上下文路徑。要將它們公開(kāi)到應(yīng)用程序之外,我們需要定義一個(gè)實(shí)現(xiàn)MicroProfile HealthCheck 接口的bean。Readiness 端應(yīng)該用@Readiness標(biāo)注,而liveness 端應(yīng)該用@Liveness標(biāo)注。

@ApplicationScoped
@Readiness
public class ReadinessHealthcheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.named("Employee Health Check").up().build();
    }

}

為了啟用Swagger文檔,我們只需要添加一個(gè)依賴項(xiàng)即可。Quarkus還為Swagger提供了內(nèi)置UI。默認(rèn)情況下,它是在開(kāi)發(fā)模式下啟用的,所以如果您愿意在生產(chǎn)環(huán)境中使用它,您應(yīng)該添加quarkus.swagger-ui.always-include=true到您的application.properties文件?,F(xiàn)在,如果通過(guò)執(zhí)行Maven命令mvn compile quarkus:dev在本地以開(kāi)發(fā)模式運(yùn)行應(yīng)用程序employee-service,您可以在URLhttp://localhost:8080/swagger-ui下查看可用的API規(guī)范。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

這是我從應(yīng)用程序啟動(dòng)時(shí)的日志。它打印監(jiān)聽(tīng)端口和加載的擴(kuò)展列表。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

6. 在本地機(jī)器上運(yùn)行微服務(wù)

因?yàn)槲覀兿M谕慌_(tái)機(jī)器上運(yùn)行多個(gè)應(yīng)用程序,所以需要覆蓋它們的默認(rèn)HTTP監(jiān)聽(tīng)端口。雖然employee-service仍然在默認(rèn)的8080 端口上運(yùn)行,但是其他微服務(wù)使用不同的端口,如下所示。

department-service: Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

organization-service: Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

讓我們測(cè)試一下Swagger UI中的服務(wù)間通信。我調(diào)用了GET /organizations/{id}/with-departments,它調(diào)用由department-service公開(kāi)的端點(diǎn)GET GET /departments/organization/{organizationId}。結(jié)果如下圖所示。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

7. 在OpenShift上運(yùn)行微服務(wù)

我們已經(jīng)完成了示例微服務(wù)體系結(jié)構(gòu)的實(shí)現(xiàn),并在本地機(jī)器上運(yùn)行它們?,F(xiàn)在,我們可以進(jìn)行最后一步,并嘗試在 Minishift上部署這些應(yīng)用程序。在OpenShift上部署Quarkus應(yīng)用程序時(shí),我們有一些不同的方法。今天,我將向您展示如何利用S2I為此構(gòu)建的機(jī)制。

我們將使用Quarkus GraalVM Native S2I Builder??梢栽?quai.io的 quarkus/ubi-quarkus-native-s2i找到。當(dāng)然,在部署應(yīng)用程序之前,我們需要先啟動(dòng)Minishift。根據(jù)Quarkus的文檔,基于GraalVM的本機(jī)構(gòu)建占用了大量?jī)?nèi)存和CPU,所以我決定為Minishift設(shè)置6GB和4個(gè)內(nèi)核。

$ minishift start --vm-driver=virtualbox --memor

此外,我們還需要稍微修改一下應(yīng)用程序的源代碼。您可能還記得,我們使用JDK 11在本地運(yùn)行它們。Quarkus S2I builder只支持JDK 8,所以我們需要在pom.xml中更改它。我們還需要包括一個(gè)聲明的本機(jī)配置文件如下:

<properties>
    <quarkus.version>0.21.1</quarkus.version>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
...
<profiles>
    <profile>
        <id>native</id>
        <activation>
            <property>
                <name>native</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupid>io.quarkus</groupid>
                    <artifactid>quarkus-maven-plugin</artifactid>
                    <version>${quarkus.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>native-image</goal>
                            </goals>
                            <configuration>
                                <enablehttpurlhandler>true</enablehttpurlhandler>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactid>maven-failsafe-plugin</artifactid>
                    <version>2.22.1</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                            <configuration>
                                <systemproperties>
                                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                                </systemproperties>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

另外在application.properties文件需要修改兩處。我們不需要覆蓋端口號(hào),因?yàn)?Minishift動(dòng)態(tài)地為每個(gè)pod分配虛擬IP。服務(wù)間的通信是通過(guò)OpenShift發(fā)現(xiàn)實(shí)現(xiàn)的,所以我們只需要設(shè)置服務(wù)的名稱而不是localhost。

quarkus.swagger-ui.always-include=true
pl.piomin.services.organization.client.DepartmentClient/mp-rest/url=http://department:8080
pl.piomin.services.organization.client.EmployeeClient/mp-rest/url=http://employee:8080

最后,我們可以將我們的應(yīng)用程序部署到Minishift上。為此,你應(yīng)使用oc客戶端執(zhí)行以下命令:

$ oc new-app quay.io/quarkus/ubi-quarkus-native-s2i:19.1.1~https://github.com/piomin/sample-quarkus-microservices.git#openshift --context-dir=employee --name=employee
$ oc new-app quay.io/quarkus/ubi-quarkus-native-s2i:19.1.1~https://github.com/piomin/sample-quarkus-microservices.git#openshift --context-dir=department --name=department
$ oc new-app quay.io/quarkus/ubi-quarkus-native-s2i:19.1.1~https://github.com/piomin/sample-quarkus-microservices.git#openshift --context-dir=organization --name=organization

正如您所看到的,可以在我的GitHub帳戶上找到找到程序源代碼,地址是https://github.com/piomin/sample-quarkus-microservices.git。在Minishift 上運(yùn)行的版本已經(jīng)在分支openshift中共享。在本地機(jī)器上運(yùn)行的版本在主分支上可用。因?yàn)樗械膽?yīng)用程序都存儲(chǔ)在一個(gè)庫(kù)中,所以我們需要為每個(gè)部署定義一個(gè)參數(shù)context-dir

我很失望。雖然為minishift 設(shè)置更多的內(nèi)存和CPU花費(fèi)了我很長(zhǎng)的時(shí)間——大約25分鐘。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

然而,經(jīng)過(guò)長(zhǎng)時(shí)間的等待,我的所有應(yīng)用程序終于都部署好了。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

我通過(guò)執(zhí)行下面可見(jiàn)的命令將它們公開(kāi)在Minishift 外??梢允褂肈NS http://${APP_NAME}-myproject.192.168.99.100.nip.io下的OpenShift路由測(cè)試它們。

$ oc expose svc employee
$ oc expose svc department
$ oc expose svc organization

此外,您還可以在OpenShift上啟用readiness 和liveness 健康檢查,因?yàn)樗鼈冊(cè)谀J(rèn)情況下是禁用的。

Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)

關(guān)于Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

當(dāng)前題目:Openshift中怎么利用Quarkus構(gòu)建一個(gè)微服務(wù)
轉(zhuǎn)載注明:http://jinyejixie.com/article2/pggjic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)網(wǎng)站設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
井陉县| 南靖县| 开江县| 亳州市| 临海市| 炎陵县| 黄大仙区| 蒙阴县| 宾阳县| 彭州市| 西盟| 泸水县| 阿坝| 合川市| 宜川县| 昭觉县| 蒙阴县| 吴忠市| 连平县| 海兴县| 中卫市| 京山县| 双辽市| 玛沁县| 康保县| 屯昌县| 哈巴河县| 新余市| 龙门县| 石景山区| 普兰店市| 凤山县| 桐柏县| 康马县| 广河县| 苏尼特右旗| 镇远县| 廉江市| 县级市| 绩溪县| 金平|